relaton-render 0.7.2 → 0.7.3

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: 6b7a094cb951866a90ce67736e150d7723366ad8f4693ac62de82fbd90fccbdc
4
- data.tar.gz: 5041e1e397d38d30c6e48b06fa0b78e09afb987c519393c7ba771a892cfb653f
3
+ metadata.gz: b64bd51a5487927e3c700f4658188e342593f85bd56abd0efb92b51d2329fe59
4
+ data.tar.gz: 21fb237d1d039c9c136bc5e3f64396437f007f690fdc1e54d557e40c722c98c5
5
5
  SHA512:
6
- metadata.gz: 758a2f69ce87e0b258a0e7f5920f29f347a9fd311a11bb31199baaaaa8f7cd4d6fc46fcfdad5b8567072372b908a13fd1b1816056da0967cefb90bf6b79f0e84
7
- data.tar.gz: a0fcbecba3f10f74b5a4dbd8ca056554c19527e5fa0277b39b007102cec98121bdfda1bc6211aa12cc8d69afbdc5e602a862015153e30b1658b4bb2a37e6f244
6
+ metadata.gz: ab48727b2054c7d8f665d409545ff07912de7170b9fdaf539bc8788b4185f9a1c7a02a90c068f00980ab98edba5c05ea1e4c60024b13c3a4e0fc855bc34be6a5
7
+ data.tar.gz: 769716704f5d77011d281ae8eac4abc6c4332763ce5fa29171537c1c80781e2ad5e6424ef3d25721743c1c8ed2653c3cda8dacc978194814cdf6e9f2658eb845
@@ -4,6 +4,8 @@ module Relaton
4
4
  def initialize(date, options)
5
5
  @date = date
6
6
  @r = options[:renderer]
7
+ @type = options[:type]
8
+ @bibitem = options[:bibitem]
7
9
  end
8
10
 
9
11
  def render
@@ -55,7 +55,7 @@ module Relaton
55
55
  def date_fields_format(hash)
56
56
  [%i(date date), %i(date_updated date_updated),
57
57
  %i(date_accessed date_accessed)].each do |k|
58
- hash[k[0]] = dateformat(hash[k[1]], hash)
58
+ hash[k[0]] = dateformat(hash[k[1]], hash, k)
59
59
  k[0] == :date && hash[:type] != "standard" and
60
60
  hash[k[0]] ||= @r.i18n.get["no_date"]
61
61
  end
@@ -191,10 +191,12 @@ module Relaton
191
191
  range(hash)
192
192
  end
193
193
 
194
- def dateformat(date, _hash)
194
+ def dateformat(date, hash, type)
195
195
  date.nil? and return nil
196
+ date.is_a?(String) and return date
196
197
  %i(from to on).each do |k|
197
- date[k] = ::Relaton::Render::Date.new(date[k], renderer: @r).render
198
+ date[k] = @r.dateklass
199
+ .new(date[k], renderer: @r, bibitem: hash, type: type).render
198
200
  end
199
201
  date_range(date)
200
202
  end
@@ -10,17 +10,58 @@ module Relaton
10
10
  # takes array of { id, type, author, date, ord, data_liquid }
11
11
  def render(ret)
12
12
  cites = citations(ret)
13
+ cites.each_value do |v|
14
+ v[:renderer] = @renderer.renderer(v[:type] || "misc")
15
+ end
16
+ enhance_data(cites)
13
17
  cites.each_key do |k|
14
18
  cites[k] = render1(cites[k])
15
19
  end
16
20
  cites
17
21
  end
18
22
 
23
+ def enhance_data(cites)
24
+ ret = extract_uris_for_lookup(cites)
25
+ ret.empty? and return
26
+ @renderer.urls_exist_concurrent(ret.keys).each do |k, v|
27
+ ret[k].each { |u| add_date_accessed(cites[u], k, v) }
28
+ end
29
+ end
30
+
31
+ def extract_uris_for_lookup(cites)
32
+ cites.each_with_object({}) do |(k, v), m|
33
+ u = extract_uri_for_lookup(v) or next
34
+ m[u] ||= []
35
+ m[u] << k
36
+ end
37
+ end
38
+
39
+ def extract_uri_for_lookup(cite)
40
+ t = cite[:renderer].template_raw
41
+ c = cite[:data_liquid]
42
+ t.is_a?(String) or return
43
+ (/\{\{\s*date_accessed\s*\}\}/.match?(t) &&
44
+ /\{\{\s*uri\s*\}\}/.match?(t) &&
45
+ c[:uri_raw] && !c[:date_accessed]) or return
46
+ c[:uri_raw]
47
+ end
48
+
49
+ def add_date_accessed(data, uri, status)
50
+ if status
51
+ data[:data_liquid][:date_accessed] = { on: ::Date.today.to_s }
52
+ data[:data_liquid] = @renderer.fieldsklass.new(renderer: @renderer)
53
+ .compound_fields_format(data[:data_liquid])
54
+ else
55
+ @renderer.url_warn(uri)
56
+ end
57
+ end
58
+
19
59
  def render1(cit)
20
- r = @renderer.renderer(cit[:type] || "misc")
21
60
  cit[:formattedref] =
22
- @renderer.valid_parse(@i18n.l10n(r.render(cit[:data_liquid])))
23
- %i(type data_liquid).each { |x| cit.delete(x) }
61
+ @renderer.valid_parse(
62
+ @i18n.l10n(cit[:renderer].render(cit[:data_liquid])),
63
+ )
64
+ %i(type data_liquid renderer).each { |x| cit.delete(x) }
24
65
  cit
25
66
  end
26
67
 
@@ -55,7 +96,7 @@ module Relaton
55
96
  def sort_ord(ret)
56
97
  ret.each do |author, v|
57
98
  v.each_key do |date|
58
- ret[author][date].sort! { |a, b| a[:ord] <=> b[:ord] }
99
+ ret[author][date].sort_by! { |a| a[:ord] }
59
100
  end
60
101
  end
61
102
  end
@@ -82,7 +123,7 @@ module Relaton
82
123
 
83
124
  def to_hash(ret)
84
125
  ret.each_with_object({}) do |(_k, v), m|
85
- v.each do |_k1, v1|
126
+ v.each_value do |v1|
86
127
  v1.each do |b|
87
128
  m[b[:id]] = { author: b[:author], date: b[:date],
88
129
  citation: "#{b[:author]} #{b[:date]}",
@@ -1,10 +1,10 @@
1
1
  require_relative "render_classes"
2
2
  require_relative "citations"
3
+ require_relative "uri"
3
4
  require "yaml"
4
5
  require "liquid"
5
6
  require "date"
6
7
  require "relaton_bib"
7
- require "net/http"
8
8
  require_relative "../template/template"
9
9
  require_relative "../../../isodoc/i18n"
10
10
 
@@ -14,7 +14,7 @@ module Relaton
14
14
  attr_reader :template, :journaltemplate, :seriestemplate, :nametemplate,
15
15
  :authorcitetemplate, :extenttemplate, :sizetemplate,
16
16
  :lang, :script, :i18n,
17
- :edition, :edition_ordinal, :date
17
+ :edition, :edition_ordinal, :date, :fieldsklass, :dateklass
18
18
 
19
19
  def initialize(opt = {})
20
20
  options = read_config.merge(Utils::string_keys(opt))
@@ -23,7 +23,9 @@ module Relaton
23
23
  root_initalize(options)
24
24
  render_initialize(options)
25
25
  @parse ||= options["parse"]
26
+ @semaphore = Mutex.new
26
27
  @urlcache = {}
28
+ @url_warned = {}
27
29
  end
28
30
 
29
31
  def read_config
@@ -38,6 +40,7 @@ module Relaton
38
40
  @sizetemplateklass = Relaton::Render::Template::Size
39
41
  @generaltemplateklass = Relaton::Render::Template::General
40
42
  @fieldsklass = Relaton::Render::Fields
43
+ @dateklass = Relaton::Render::Date
41
44
  @parseklass = Relaton::Render::Parse
42
45
  end
43
46
 
@@ -133,7 +136,6 @@ module Relaton
133
136
  raise "No renderer defined for #{type}"
134
137
  @type == "general" || @type == type or
135
138
  raise "No renderer defined for #{type}"
136
-
137
139
  ret
138
140
  end
139
141
 
@@ -169,6 +171,7 @@ module Relaton
169
171
  end
170
172
 
171
173
  # expect array of Relaton objects, in sorted order
174
+ # enhance_data is skipped here, and is done in batch inside Citations
172
175
  def render_all(bib, type: "author-date")
173
176
  bib = sanitise_citations_input(bib) or return
174
177
  Citations.new(type: type, renderer: self, i18n: @i18n)
@@ -183,7 +186,6 @@ module Relaton
183
186
  def sanitise_citations_input_string(bib)
184
187
  p = Nokogiri::XML(bib) or return
185
188
  (p.errors.empty? && p.root.at("./bibitem")) or return nil
186
-
187
189
  p.root.xpath("./bibitem").each_with_object([]) do |b, m|
188
190
  m << RelatonBib::XMLParser.from_xml(b.to_xml)
189
191
  end
@@ -210,11 +212,16 @@ module Relaton
210
212
  data[:uri_raw] && !data[:date_accessed]) or return
211
213
  if url_exist?(data[:uri_raw])
212
214
  data[:date_accessed] = { on: ::Date.today.to_s }
213
- else
214
- warn "BIBLIOGRAPHY WARNING: cannot access #{data[:uri_raw]}"
215
+ else url_warn(data[:uri_raw])
215
216
  end
216
217
  end
217
218
 
219
+ def url_warn(uri)
220
+ @url_warned[uri] and return
221
+ warn "BIBLIOGRAPHY WARNING: cannot access #{uri}"
222
+ @url_warned[uri] = true
223
+ end
224
+
218
225
  private
219
226
 
220
227
  def template_hash_fill(templates)
@@ -224,35 +231,6 @@ module Relaton
224
231
  m[type] = template
225
232
  end
226
233
  end
227
-
228
- def url_exist?(url_string)
229
- url = URI.parse(url_string)
230
- url.host or return true # allow file URLs
231
- res = access_url(url) or return false
232
- res.is_a?(Net::HTTPRedirection) and return url_exist?(res["location"])
233
- res.code[0] != "4"
234
- rescue Errno::ENOENT, SocketError
235
- false # false if can't find the server
236
- end
237
-
238
- def access_url(url)
239
- path = url.path or return false
240
- path.empty? and path = "/"
241
- @urlcache.key?(url.to_s) and return @urlcache[url.to_s]
242
- @urlcache[url.to_s] = url_head(url, path)
243
- @urlcache[url.to_s]
244
- rescue => e
245
- warn e.backtrace
246
- false
247
- end
248
-
249
- def url_head(url, path)
250
- Net::HTTP.start(url.host, url.port,
251
- read_timeout: 2, open_timeout: 2,
252
- use_ssl: url.scheme == "https") do |http|
253
- http.request_head(path)
254
- end
255
- end
256
234
  end
257
235
  end
258
236
  end
@@ -0,0 +1,56 @@
1
+ require "concurrent"
2
+ require "net/http"
3
+ require "uri"
4
+
5
+ module Relaton
6
+ module Render
7
+ class General
8
+ def url_exist?(url_string)
9
+ url = URI.parse(url_string)
10
+ url.host or return true # allow file URLs
11
+ res = access_url(url) or return false
12
+ res.is_a?(Net::HTTPRedirection) and return url_exist?(res["location"])
13
+ res.code[0] != "4"
14
+ rescue Errno::ENOENT, SocketError
15
+ false # false if can't find the server
16
+ end
17
+
18
+ def access_url(url)
19
+ path = url.path or return false
20
+ path.empty? and path = "/"
21
+ url_head(url, path)
22
+ rescue StandardError => e
23
+ warn e
24
+ false
25
+ end
26
+
27
+ def url_head(url, path)
28
+ ret = nil
29
+ @semaphore.synchronize { ret = @urlcache[url.to_s] }
30
+ ret and return ret
31
+ ret = Net::HTTP.start(url.host, url.port,
32
+ read_timeout: 2, open_timeout: 2,
33
+ use_ssl: url.scheme == "https") do |http|
34
+ http.request_head(path)
35
+ end
36
+ @semaphore.synchronize { @urlcache[url.to_s] = ret }
37
+ ret
38
+ end
39
+
40
+ def urls_exist_concurrent(urls)
41
+ responses = Concurrent::Array.new
42
+ thread_pool = Concurrent::FixedThreadPool.new(5)
43
+ urls.each do |u|
44
+ thread_pool.post { responses << url_exist_async?(u) }
45
+ end
46
+ thread_pool.shutdown
47
+ thread_pool.wait_for_termination
48
+ responses.each_with_object({}) { |n, m| m[n[:url]] = n[:status] }
49
+ end
50
+
51
+ def url_exist_async?(url_string)
52
+ { url: url_string, status: url_exist?(url_string) }
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,5 +1,5 @@
1
1
  module Relaton
2
2
  module Render
3
- VERSION = "0.7.2".freeze
3
+ VERSION = "0.7.3".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relaton-render
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-03-05 00:00:00.000000000 Z
11
+ date: 2024-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -213,6 +213,7 @@ files:
213
213
  - lib/relaton/render/general/config.yml
214
214
  - lib/relaton/render/general/render.rb
215
215
  - lib/relaton/render/general/render_classes.rb
216
+ - lib/relaton/render/general/uri.rb
216
217
  - lib/relaton/render/parse/parse.rb
217
218
  - lib/relaton/render/parse/parse_contributors.rb
218
219
  - lib/relaton/render/parse/parse_extract.rb