relaton 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
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