relaton-render 0.7.2 → 0.7.3

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: 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