relaton 0.2.5 → 0.2.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c1beef6d057ce75ecd9f18f02d3ce887bf9c8d259c0ac7d159f24d8584134c3
4
- data.tar.gz: 62db2b47dae11069a14dc8eb83dcc62090aec6a4d586508d00cf81736d9492a1
3
+ metadata.gz: 0b1872ecb2665f86758a05dd822d450d6daf37cf7865f0faf17878a494e1e17c
4
+ data.tar.gz: 464054cbb8b6d3475ff016ce8748bc88105cced709187751421cba7124943d0e
5
5
  SHA512:
6
- metadata.gz: 83a73440d1eb4f63c12e33d296075a7e46759db37bafe40bda57369d6786202e57eb17426f4975d1c1b005fa7dab76fa06996ecc538f608060f269625605a3b0
7
- data.tar.gz: e1e8ab5afcb76904239547bbbdc4dca80a3e8dd0b2ca7040f721487970224c010b5e50b2357b9a8121a6147c05091d2babed9745c8b626cd282199b6849f21b0
6
+ metadata.gz: 62ed5b9d6a9002d748e9069651b7dda734d8e61b7f09aff340fabf563f4daef4c60b61131634dcad8f3d4faa174b64b873e3cb3e074279013807e8c89168eede
7
+ data.tar.gz: a389d31e90fd4a6b238a554998f9936e34324abfa41c21669212d3a20800cb538e37116a7b6d731a14a1920c46fdd366579aa2df736fbb65a52da30c0a644e56
@@ -1,13 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- relaton (0.2.5)
4
+ relaton (0.2.6)
5
5
  algoliasearch
6
- gbbib (~> 0.3.1)
7
- iecbib (~> 0.1.1)
8
- ietfbib (~> 0.4.1)
9
- iso-bib-item (~> 0.3.0)
10
- isobib (~> 0.3.1)
6
+ gbbib (~> 0.4.0)
7
+ iecbib (~> 0.2.0)
8
+ ietfbib (~> 0.4.2)
9
+ iso-bib-item (~> 0.4.1)
10
+ isobib (~> 0.4.0)
11
11
 
12
12
  GEM
13
13
  remote: https://rubygems.org/
@@ -28,10 +28,10 @@ GEM
28
28
  ffi (1.9.25)
29
29
  formatador (0.2.5)
30
30
  gb-agencies (0.0.3)
31
- gbbib (0.3.1)
31
+ gbbib (0.4.0)
32
32
  cnccs (~> 0.1.1)
33
33
  gb-agencies (~> 0.0.1)
34
- iso-bib-item (~> 0.3.0)
34
+ iso-bib-item (~> 0.4.1)
35
35
  guard (2.14.2)
36
36
  formatador (>= 0.2.4)
37
37
  listen (>= 2.7, < 4.0)
@@ -47,19 +47,19 @@ GEM
47
47
  guard-compat (~> 1.1)
48
48
  rspec (>= 2.99.0, < 4.0)
49
49
  httpclient (2.8.3)
50
- iecbib (0.1.2)
50
+ iecbib (0.2.0)
51
51
  addressable
52
- iso-bib-item (~> 0.3.0)
53
- ietfbib (0.4.1)
54
- iso-bib-item (~> 0.3.0)
55
- iso-bib-item (0.3.1)
52
+ iso-bib-item (~> 0.4.0)
53
+ ietfbib (0.4.2)
54
+ iso-bib-item (~> 0.4.1)
55
+ iso-bib-item (0.4.1)
56
56
  isoics (~> 0.1.6)
57
57
  nokogiri (~> 1.8.4)
58
58
  ruby_deep_clone (~> 0.8.0)
59
- isobib (0.3.1)
59
+ isobib (0.4.0)
60
60
  algoliasearch
61
- iecbib (~> 0.1.1)
62
- iso-bib-item (~> 0.3.0)
61
+ iecbib (~> 0.2.0)
62
+ iso-bib-item (~> 0.4.0)
63
63
  isoics (0.1.7)
64
64
  jaro_winkler (1.5.1)
65
65
  json (2.1.0)
@@ -71,7 +71,7 @@ GEM
71
71
  method_source (0.9.0)
72
72
  mini_portile2 (2.3.0)
73
73
  nenv (0.3.0)
74
- nokogiri (1.8.4)
74
+ nokogiri (1.8.5)
75
75
  mini_portile2 (~> 2.3.0)
76
76
  notiffany (0.1.1)
77
77
  nenv (~> 0.1)
@@ -98,7 +98,7 @@ GEM
98
98
  rspec-mocks (~> 3.8.0)
99
99
  rspec-core (3.8.0)
100
100
  rspec-support (~> 3.8.0)
101
- rspec-expectations (3.8.1)
101
+ rspec-expectations (3.8.2)
102
102
  diff-lcs (>= 1.2.0, < 2.0)
103
103
  rspec-support (~> 3.8.0)
104
104
  rspec-mocks (3.8.0)
@@ -144,4 +144,4 @@ DEPENDENCIES
144
144
  timecop (~> 0.9)
145
145
 
146
146
  BUNDLED WITH
147
- 1.16.2
147
+ 1.16.6
@@ -1,5 +1,6 @@
1
- require "pstore"
1
+ # require "pstore"
2
2
  require_relative "registry"
3
+ require_relative 'db_cache'
3
4
 
4
5
  module Relaton
5
6
  class RelatonError < StandardError; end
@@ -7,31 +8,31 @@ module Relaton
7
8
  class Db
8
9
  SUPPORTED_GEMS = %w[isobib ietfbib gbbib iecbib].freeze
9
10
 
10
- # @param global_cache [String] filename of global DB
11
- # @param local_cache [String] filename of local DB
11
+ # @param global_cache [String] directory of global DB
12
+ # @param local_cache [String] directory of local DB
12
13
  def initialize(global_cache, local_cache)
13
14
  register_gems
15
+ @registry = Relaton::Registry.instance
14
16
  @db = open_cache_biblio(global_cache)
15
17
  @local_db = open_cache_biblio(local_cache, global: false)
16
18
  @db_name = global_cache
17
19
  @local_db_name = local_cache
18
- @registry = Relaton::Registry.instance
19
20
  end
20
21
 
21
22
  def register_gems
22
- puts "[relaton] detecting backends:"
23
+ puts "[relaton] Info: detecting backends:"
23
24
  SUPPORTED_GEMS.each do |b|
24
- puts b
25
+ # puts b
25
26
  begin
26
27
  require b
27
28
  rescue LoadError
28
- puts "[relaton] backend #{b} not present"
29
+ puts "[relaton] Error: backend #{b} not present"
29
30
  end
30
31
  end
31
32
  end
32
33
 
33
34
  # The class of reference requested is determined by the prefix of the code:
34
- # GB Standard for gbbib, IETF for ietfbib, ISO for isobib, IEC or IEV for iecbib,
35
+ # GB Standard for gbbib, IETF for ietfbib, ISO for isobib, IEC or IEV for iecbib,
35
36
  # @param code [String] the ISO standard Code to look up (e.g. "ISO 9000")
36
37
  # @param year [String] the year the standard was published (optional)
37
38
  # @param opts [Hash] options; restricted to :all_parts if all-parts reference is required
@@ -63,10 +64,10 @@ module Relaton
63
64
  # @return [Hash]
64
65
  def load_entry(key)
65
66
  unless @local_db.nil?
66
- entry = @local_db.transaction { @local_db[key] }
67
+ entry = @local_db[key]
67
68
  return entry if entry
68
69
  end
69
- @db.transaction { @db[key] }
70
+ @db[key]
70
71
  end
71
72
 
72
73
  # @param key [String]
@@ -74,29 +75,29 @@ module Relaton
74
75
  # @option value [Date] "fetched"
75
76
  # @option value [IsoBibItem::IsoBibliographicItem] "bib"
76
77
  def save_entry(key, value)
77
- @db.nil? or @db.transaction { @db[key] = value }
78
- @local_db.nil? or @local_db.transaction { @local_db[key] = value }
78
+ @db.nil? || (@db[key] = value)
79
+ @local_db.nil? || (@local_db[key] = value)
79
80
  end
80
81
 
81
82
  # list all entries as a serialization
83
+ # @return [String]
82
84
  def to_xml
83
85
  db = @local_db || @db || return
84
- db.transaction do
85
- Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
86
- xml.documents do
87
- db.roots.reject { |key| key == :version }.
88
- each { |key| db[key]&.fetch("bib")&.to_xml(xml, {}) }
89
- end
90
- end.to_xml
91
- end
86
+ Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
87
+ xml.documents do
88
+ xml.parent.add_child db.all.join(" ")
89
+ end
90
+ end.to_xml
92
91
  end
93
92
 
94
93
  private
95
94
 
95
+ # @param code [String] code of standard
96
+ # @return [Symbol] standard class name
96
97
  def standard_class(code)
97
98
  @registry.processors.each do |name, processor|
98
99
  return name if /^#{processor.prefix}/.match(code) ||
99
- processor.defaultprefix.match(code)
100
+ processor.defaultprefix.match(code)
100
101
  end
101
102
  allowed = @registry.processors.reduce([]) do |m, (_k, v)|
102
103
  m << v.prefix
@@ -106,6 +107,12 @@ module Relaton
106
107
  end
107
108
 
108
109
  # TODO: i18n
110
+ # Fofmat ID
111
+ # @param code [String]
112
+ # @param year [String]
113
+ # @param opts [Hash]
114
+ # @param stdClass [Symbol]
115
+ # @return [Array]
109
116
  def std_id(code, year, opts, stdclass)
110
117
  prefix, code = strip_id_wrapper(code, stdclass)
111
118
  ret = code
@@ -114,14 +121,18 @@ module Relaton
114
121
  ["#{prefix}(#{ret})", code]
115
122
  end
116
123
 
124
+ # Find prefix and clean code
125
+ # @param code [String]
126
+ # @param stdClass [Symbol]
127
+ # @return [Array]
117
128
  def strip_id_wrapper(code, stdclass)
118
129
  prefix = @registry.processors[stdclass].prefix
119
130
  code = code.sub(/^#{prefix}\((.+)\)$/, "\\1")
120
131
  [prefix, code]
121
132
  end
122
133
 
123
- def bib_retval(entry)
124
- entry["bib"] == "not_found" ? nil : entry["bib"]
134
+ def bib_retval(entry, stdclass)
135
+ entry =~ /^not_found/ ? nil : @registry.processors[stdclass].from_xml(entry)
125
136
  end
126
137
 
127
138
  # @param code [String]
@@ -132,21 +143,17 @@ module Relaton
132
143
  id, searchcode = std_id(code, year, opts, stdclass)
133
144
  db = @local_db || @db
134
145
  altdb = @local_db && @db ? @db : nil
135
- return bib_retval(new_bib_entry(searchcode, year, opts, stdclass)) if db.nil?
136
- db.transaction do
137
- db.delete(id) unless valid_bib_entry?(db[id], year)
138
- if altdb
139
- altdb.transaction do
140
- db[id] ||= altdb[id]
141
- db[id] ||= new_bib_entry(searchcode, year, opts, stdclass)
142
- altdb[id] = db[id] if !valid_bib_entry?(altdb[id], year)
143
- bib_retval(db[id])
144
- end
145
- else
146
- db[id] ||= new_bib_entry(searchcode, year, opts, stdclass)
147
- bib_retval(db[id])
148
- end
146
+ return bib_retval(new_bib_entry(searchcode, year, opts, stdclass), stdclass) if db.nil?
147
+
148
+ db.delete(id) unless db.valid_entry?(id, year)
149
+ if altdb
150
+ db[id] ||= altdb[id]
151
+ db[id] ||= new_bib_entry(searchcode, year, opts, stdclass)
152
+ altdb[id] = db[id] if !altdb.valid_entry?(id, year)
153
+ else
154
+ db[id] ||= new_bib_entry(searchcode, year, opts, stdclass)
149
155
  end
156
+ bib_retval(db[id], stdclass)
150
157
  end
151
158
 
152
159
  # hash uses => , because the hash is imported from JSON
@@ -157,51 +164,56 @@ module Relaton
157
164
  # @return [Hash]
158
165
  def new_bib_entry(code, year, opts, stdclass)
159
166
  bib = @registry.processors[stdclass].get(code, year, opts)
160
- bib = "not_found" if bib.nil?
161
- { "fetched" => Date.today, "bib" => bib }
167
+ bib = "not_found #{Date.today}" if bib.nil? || bib.empty?
168
+ bib
162
169
  end
163
170
 
164
171
  # if cached reference is undated, expire it after 60 days
165
172
  # @param bib [Hash]
166
173
  # @param year [String]
167
- def valid_bib_entry?(bib, year)
168
- bib&.is_a?(Hash) && bib&.has_key?("bib") && bib&.has_key?("fetched") &&
169
- (year || Date.today - bib["fetched"] < 60)
170
- end
174
+ # def valid_bib_entry?(bib, year)
175
+ # bib&.is_a?(Hash) && bib&.has_key?("bib") && bib&.has_key?("fetched") &&
176
+ # (year || Date.today - bib["fetched"] < 60)
177
+ # end
171
178
 
172
- # @param filename [String] DB filename
179
+ # @param dir [String] DB directory
173
180
  # @param global [TrueClass, FalseClass]
174
181
  # @return [PStore]
175
- def open_cache_biblio(filename, global: true)
176
- return nil if filename.nil?
177
- db = PStore.new filename
178
- if File.exist? filename
182
+ def open_cache_biblio(dir, global: true)
183
+ return nil if dir.nil?
184
+ db = DbCache.new dir
185
+ if File.exist? dir
179
186
  if global
180
- unless check_cache_version(db)
181
- File.delete filename
187
+ unless db.check_version?
188
+ FileUtils.rm_rf dir + '/.'
182
189
  warn "Global cache version is obsolete and cleared."
183
190
  end
184
- set_cache_version db
185
- elsif check_cache_version(db) then db
191
+ db.set_version
192
+ elsif db.check_version? then db
186
193
  else
187
194
  warn "Local cache version is obsolete."
188
195
  nil
189
196
  end
190
- else
191
- set_cache_version db
197
+ else db.set_version
192
198
  end
193
199
  end
194
200
 
195
- def check_cache_version(cache_db)
196
- cache_db.transaction { cache_db[:version] == VERSION }
197
- end
201
+ # Check if version of the DB match to the gem version.
202
+ # @param cache_db [String] DB directory
203
+ # @return [TrueClass, FalseClass]
204
+ # def check_cache_version(cache_db)
205
+ # cache_db.transaction { cache_db[:version] == VERSION }
206
+ # end
198
207
 
199
- def set_cache_version(cache_db)
200
- unless File.exist? cache_db.path
201
- cache_db.transaction { cache_db[:version] = VERSION }
202
- end
203
- cache_db
204
- end
208
+ # Set version of the DB to the gem version.
209
+ # @param cache_db [String] DB directory
210
+ # @return [Pstore]
211
+ # def set_cache_version(cache_db)
212
+ # unless File.exist? cache_db.path
213
+ # cache_db.transaction { cache_db[:version] = VERSION }
214
+ # end
215
+ # cache_db
216
+ # end
205
217
 
206
218
  # @param enstry [String] entry in XML format
207
219
  # @return [IsoBibItem::IsoBibliographicItem]
@@ -0,0 +1,111 @@
1
+ module Relaton
2
+ class DbCache
3
+ # @return [String]
4
+ attr_reader :dir
5
+
6
+ # @param dir [String] DB directory
7
+ def initialize(dir)
8
+ @dir = dir
9
+ Dir.mkdir @dir unless Dir.exist? @dir
10
+ fiele_version = "#{@dir}/version"
11
+ File.write fiele_version, VERSION unless File.exist? fiele_version
12
+ end
13
+
14
+ # Save item
15
+ # @param key [String]
16
+ # @param value [String] Bibitem xml serialization
17
+ def []=(key, value)
18
+ return if value.nil?
19
+ prefix_dir = "#{@dir}/#{prefix(key)}"
20
+ Dir.mkdir prefix_dir unless Dir.exist? prefix_dir
21
+ File.write filename(key), value
22
+ end
23
+
24
+ # Read item
25
+ # @param key [String]
26
+ # @return [String]
27
+ def [](key)
28
+ file = filename key
29
+ return unless File.exist? file
30
+
31
+ File.read(file)
32
+ end
33
+
34
+ # Return fetched date
35
+ # @param key [String]
36
+ # @return [String]
37
+ def fetched(key)
38
+ value = self[key]
39
+ return unless value
40
+ if value =~ /^not_found/
41
+ value.match(/\d{4}-\d{2}-\d{2}/).to_s
42
+ else
43
+ doc = Nokogiri::XML value
44
+ doc.at('/bibitem/fetched').text
45
+ end
46
+ end
47
+
48
+ # Returns all items
49
+ # @return [Array<Hash>]
50
+ def all
51
+ Dir.glob("testcache/**/*.xml").sort.map do |f|
52
+ File.read(f)
53
+ end
54
+ end
55
+
56
+ # Delete item
57
+ # @param key [String]
58
+ def delete(key)
59
+ file = filename key
60
+ File.delete file if File.exist? file
61
+ end
62
+
63
+ # Check if version of the DB match to the gem version.
64
+ # @return [TrueClass, FalseClass]
65
+ def check_version?
66
+ v = File.read @dir + "/version"
67
+ v == VERSION
68
+ end
69
+
70
+ # Set version of the DB to the gem version.
71
+ # @return [Relaton::DbCache]
72
+ def set_version
73
+ File.write @dir + "/version", VERSION
74
+ self
75
+ end
76
+
77
+ # if cached reference is undated, expire it after 60 days
78
+ # @param key [String]
79
+ # @param year [String]
80
+ def valid_entry?(key, year)
81
+ datestr = fetched key
82
+ return false unless datestr
83
+ date = Date.parse datestr
84
+ year || Date.today - date < 60
85
+ end
86
+
87
+ private
88
+
89
+ # Return item's file name
90
+ # @param key [String]
91
+ # @return [String]
92
+ def filename(key)
93
+ prefcode = key.downcase.match /^(?<prefix>[^\(]+)\((?<code>[^\)]+)/
94
+ if prefcode
95
+ "#{@dir}/#{prefcode[:prefix]}/#{prefcode[:code].gsub(/[-:\s\/]/, '_')}.xml"
96
+ else
97
+ "#{@dir}/#{key.gsub(/[-:\s]/, '_')}.xml"
98
+ end
99
+ end
100
+
101
+ # Return item's subdir
102
+ # @param key [String]
103
+ # @return [String]
104
+ def prefix(key)
105
+ # @registry.processors.detect do |_n, p|
106
+ # /^#{p.prefix}/.match(key) || processor.defaultprefix.match(key)
107
+ # end[1].prefix.downcase
108
+ key.downcase.match(/^[^\(]+(?=\()/).to_s
109
+ end
110
+ end
111
+ end