relaton 3.0.0.pre.alpha.5 → 3.0.0.pre.alpha.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 +4 -4
- data/lib/relaton/3gpp/bibliography.rb +19 -6
- data/lib/relaton/3gpp/processor.rb +6 -0
- data/lib/relaton/bib/item_data.rb +14 -0
- data/lib/relaton/bipm/bibliography.rb +24 -21
- data/lib/relaton/bsi/bibliography.rb +26 -23
- data/lib/relaton/calconnect/bibliography.rb +6 -6
- data/lib/relaton/calconnect/hit_collection.rb +4 -1
- data/lib/relaton/ccsds/bibliography.rb +15 -10
- data/lib/relaton/ccsds/hit_collection.rb +1 -1
- data/lib/relaton/ccsds/processor.rb +3 -2
- data/lib/relaton/cen/bibliography.rb +27 -24
- data/lib/relaton/cie/bibliography.rb +11 -9
- data/lib/relaton/cie/scrapper.rb +15 -8
- data/lib/relaton/core/processor.rb +61 -8
- data/lib/relaton/core/request_error.rb +21 -3
- data/lib/relaton/db/cache.rb +49 -19
- data/lib/relaton/db/cache_entry.rb +9 -0
- data/lib/relaton/db/registry.rb +128 -28
- data/lib/relaton/db.rb +162 -48
- data/lib/relaton/ecma/bibliography.rb +18 -13
- data/lib/relaton/etsi/bibliography.rb +8 -7
- data/lib/relaton/gb/bibliography.rb +20 -12
- data/lib/relaton/iala/bibliography.rb +15 -12
- data/lib/relaton/iana/bibliography.rb +12 -12
- data/lib/relaton/iana/parser.rb +5 -2
- data/lib/relaton/iec/bibliography.rb +18 -7
- data/lib/relaton/iec/processor.rb +5 -0
- data/lib/relaton/ieee/bibliography.rb +19 -13
- data/lib/relaton/ieee/processor.rb +16 -0
- data/lib/relaton/ieee/rawbib_id_parser.rb +2 -2
- data/lib/relaton/ietf/bibliography.rb +11 -9
- data/lib/relaton/ietf/scraper.rb +5 -4
- data/lib/relaton/iso/bibliography.rb +11 -9
- data/lib/relaton/itu/bibliography.rb +9 -4
- data/lib/relaton/jis/bibliography.rb +22 -11
- data/lib/relaton/nist/bibliography.rb +25 -21
- data/lib/relaton/oasis/bibliography.rb +16 -13
- data/lib/relaton/ogc/bibliography.rb +15 -14
- data/lib/relaton/ogc/hit_collection.rb +9 -7
- data/lib/relaton/ogc/processor.rb +7 -1
- data/lib/relaton/omg/bibliography.rb +9 -9
- data/lib/relaton/omg/scraper.rb +3 -2
- data/lib/relaton/plateau/bibliography.rb +9 -7
- data/lib/relaton/plateau/hit_collection.rb +2 -1
- data/lib/relaton/version.rb +1 -1
- data/lib/relaton/xsf/bibliography.rb +11 -6
- metadata +18 -4
|
@@ -15,10 +15,10 @@ module Relaton
|
|
|
15
15
|
module Bibliography
|
|
16
16
|
SOURCE = "https://raw.githubusercontent.com/relaton/relaton-data-iana/refs/heads/v2/"
|
|
17
17
|
|
|
18
|
-
# @param
|
|
18
|
+
# @param ref [String, Pubid::Iana::Identifier]
|
|
19
19
|
# @return [Relaton::Iana::Item, nil]
|
|
20
|
-
def search(
|
|
21
|
-
pubid = parse_ref
|
|
20
|
+
def search(ref)
|
|
21
|
+
pubid = parse_ref ref
|
|
22
22
|
return unless pubid
|
|
23
23
|
|
|
24
24
|
# Pass the pubid so Relaton::Index narrows candidates by number via
|
|
@@ -34,19 +34,19 @@ module Relaton
|
|
|
34
34
|
raise Relaton::RequestError, e.message
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
# @param ref [String] the IANA registry slug to look up
|
|
37
|
+
# @param ref [String, Pubid::Iana::Identifier] the IANA registry slug to look up
|
|
38
38
|
# @param year [String, NilClass] not used
|
|
39
39
|
# @param opts [Hash] options
|
|
40
40
|
# @return [Relaton::Iana::Item, nil]
|
|
41
41
|
def get(ref, _year = nil, _opts = {})
|
|
42
|
-
Util.info "Fetching from Relaton repository ...", key: ref
|
|
42
|
+
Util.info "Fetching from Relaton repository ...", key: ref.to_s
|
|
43
43
|
result = search(ref)
|
|
44
44
|
unless result
|
|
45
|
-
Util.info "Not found.", key: ref
|
|
45
|
+
Util.info "Not found.", key: ref.to_s
|
|
46
46
|
return
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
Util.info "Found: `#{result.docidentifier[0].content}`", key: ref
|
|
49
|
+
Util.info "Found: `#{result.docidentifier[0].content}`", key: ref.to_s
|
|
50
50
|
result
|
|
51
51
|
end
|
|
52
52
|
|
|
@@ -63,14 +63,14 @@ module Relaton
|
|
|
63
63
|
# RuntimeError on anything else, and a citation relaton cannot parse is a
|
|
64
64
|
# miss, not an error — `#get` reports it as "Not found.".
|
|
65
65
|
#
|
|
66
|
-
# @param
|
|
66
|
+
# @param ref [String, Pubid::Iana::Identifier]
|
|
67
67
|
# @return [Pubid::Iana::Identifier, nil]
|
|
68
|
-
def parse_ref(
|
|
69
|
-
return
|
|
68
|
+
def parse_ref(ref)
|
|
69
|
+
return ref unless ref.is_a? String
|
|
70
70
|
|
|
71
|
-
::Pubid::Iana::Identifier.parse
|
|
71
|
+
::Pubid::Iana::Identifier.parse ref
|
|
72
72
|
rescue StandardError => e
|
|
73
|
-
Util.warn "Failed to parse pubid `#{
|
|
73
|
+
Util.warn "Failed to parse pubid `#{ref}`: #{e.message}"
|
|
74
74
|
nil
|
|
75
75
|
end
|
|
76
76
|
|
data/lib/relaton/iana/parser.rb
CHANGED
|
@@ -125,8 +125,11 @@ module Relaton
|
|
|
125
125
|
# @return [Array<Relaton::Bib::Date>] date
|
|
126
126
|
#
|
|
127
127
|
def parse_date
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
# moxml 0.5.98 drops every branch after the second in an N>=3 union
|
|
129
|
+
# under the reserved `xmlns` prefix (lutaml/moxml#315), which silently
|
|
130
|
+
# stripped `updated` dates from every crawled registry.
|
|
131
|
+
d = %w[created published updated].flat_map do |type|
|
|
132
|
+
@xml.xpath("./xmlns:#{type}", NS).map { |dt| Bib::Date.new(type: dt.name, at: dt.text) }
|
|
130
133
|
end
|
|
131
134
|
result = d.none? && @rootdoc ? @rootdoc.date : d
|
|
132
135
|
@errors[:date] &&= result.empty?
|
|
@@ -24,18 +24,29 @@ module Relaton
|
|
|
24
24
|
raise Relaton::RequestError, e.message
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
# @param
|
|
27
|
+
# @param ref [String, Pubid::Iec::Identifier] the IEC standard code to
|
|
28
|
+
# look up (e.g. "IEC 8000"), or the parse that Relaton::Db routed
|
|
29
|
+
# with (relaton#205); a pubid is never mutated
|
|
28
30
|
# @param year [String] the year the standard was published (optional)
|
|
29
31
|
# @param opts [Hash] options; restricted to :all_parts if all-parts
|
|
30
32
|
# reference is required
|
|
31
33
|
# @return [Relaton::Iec::ItemData, nil]
|
|
32
|
-
def get(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
def get(ref, year = nil, opts = {}) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/MethodLength
|
|
35
|
+
if ref.is_a?(String)
|
|
36
|
+
opts[:all_parts] ||= ref.match?(/\s\(all parts\)/)
|
|
37
|
+
text = ref.sub(/\s\(all parts\)/, "")
|
|
38
|
+
return iev if text.casecmp("IEV").zero?
|
|
39
|
+
|
|
40
|
+
pubid = ::Pubid::Iec::Identifier.parse text.upcase
|
|
41
|
+
elsif ref.all_parts?
|
|
42
|
+
opts[:all_parts] = true
|
|
43
|
+
pubid = ref.identifiers.first
|
|
44
|
+
else
|
|
45
|
+
pubid = ref
|
|
46
|
+
end
|
|
38
47
|
if year
|
|
48
|
+
# Copy first: a caller's pubid is also its Db cache key.
|
|
49
|
+
pubid = pubid.class.from_hash(pubid.to_hash)
|
|
39
50
|
pubid.date = ::Pubid::Components::Date.new(year: year.to_s)
|
|
40
51
|
end
|
|
41
52
|
|
|
@@ -63,7 +63,12 @@ module Relaton
|
|
|
63
63
|
|
|
64
64
|
# @param code [String]
|
|
65
65
|
# @return [String, nil]
|
|
66
|
+
# Only a URN: `Relaton::Iec.urn_to_code` splits on `:`, so it would
|
|
67
|
+
# rewrite any reference with enough colons
|
|
68
|
+
# (`IEC 60034-1:1969+AMD1:1977+AMD2:1979+AMD3:1980 CSV`).
|
|
66
69
|
def urn_to_code(code)
|
|
70
|
+
return unless code.match?(/\Aurn:/i)
|
|
71
|
+
|
|
67
72
|
require_relative "../iec"
|
|
68
73
|
Relaton::Iec.urn_to_code code
|
|
69
74
|
end
|
|
@@ -7,11 +7,12 @@ module Relaton
|
|
|
7
7
|
#
|
|
8
8
|
# Search IEEE bibliography item by reference.
|
|
9
9
|
#
|
|
10
|
-
# @param
|
|
10
|
+
# @param ref [String, Pubid::Ieee::Identifier] the reference, or its
|
|
11
|
+
# parse from Relaton::Db (relaton#205)
|
|
11
12
|
#
|
|
12
13
|
# @return [Relaton::Ieee::ItemData, nil]
|
|
13
14
|
#
|
|
14
|
-
def search(
|
|
15
|
+
def search(ref) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
15
16
|
index = Relaton::Index.find_or_create :ieee, url: "#{GH_URL}#{INDEXFILE}.zip", file: "#{INDEXFILE}.yaml",
|
|
16
17
|
pubid_class: ::Pubid::Ieee::Identifier
|
|
17
18
|
# Pass the parsed pubid (not the raw String) so index-v2 narrows
|
|
@@ -20,7 +21,7 @@ module Relaton
|
|
|
20
21
|
# unparseable/partial ref falls back to the full-scan String search.
|
|
21
22
|
# Rows are Pubid::Ieee::Identifier objects (not Comparable), so pick by
|
|
22
23
|
# the string form.
|
|
23
|
-
pubid = parse_pubid
|
|
24
|
+
pubid = parse_pubid ref
|
|
24
25
|
needle = pubid.to_s
|
|
25
26
|
row = index.search(pubid) { |r| r[:id].to_s.include?(needle) }.min_by { |r| r[:id].to_s }
|
|
26
27
|
return unless row
|
|
@@ -36,20 +37,22 @@ module Relaton
|
|
|
36
37
|
#
|
|
37
38
|
# Get IEEE bibliography item by reference.
|
|
38
39
|
#
|
|
39
|
-
# @param
|
|
40
|
+
# @param ref [String, Pubid::Ieee::Identifier] the IEEE standard
|
|
41
|
+
# reference to look up (e.g. "IEEE 528-2019"), or its parse from
|
|
42
|
+
# Relaton::Db (relaton#205)
|
|
40
43
|
# @param year [String] the year the standard was published (optional)
|
|
41
44
|
# @param opts [Hash] options
|
|
42
45
|
#
|
|
43
46
|
# @return [Relaton::Ieee::ItemData, nil]
|
|
44
47
|
#
|
|
45
|
-
def get(
|
|
46
|
-
Util.info "Fetching from Relaton repository ...", key:
|
|
47
|
-
item = search(
|
|
48
|
+
def get(ref, _year = nil, _opts = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
49
|
+
Util.info "Fetching from Relaton repository ...", key: ref.to_s
|
|
50
|
+
item = search(ref)
|
|
48
51
|
if item
|
|
49
|
-
Util.info "Found: `#{item.docidentifier.first.content}`", key:
|
|
52
|
+
Util.info "Found: `#{item.docidentifier.first.content}`", key: ref.to_s
|
|
50
53
|
item
|
|
51
54
|
else
|
|
52
|
-
Util.info "Not found.", key:
|
|
55
|
+
Util.info "Not found.", key: ref.to_s
|
|
53
56
|
nil
|
|
54
57
|
end
|
|
55
58
|
end
|
|
@@ -60,12 +63,15 @@ module Relaton
|
|
|
60
63
|
# return the raw String when pubid can't parse it (e.g. a partial ref) so
|
|
61
64
|
# the search falls back to the substring scan.
|
|
62
65
|
#
|
|
63
|
-
# @param
|
|
66
|
+
# @param ref [String, ::Pubid::Ieee::Identifier]
|
|
64
67
|
# @return [::Pubid::Ieee::Identifier, String]
|
|
65
|
-
def parse_pubid(
|
|
66
|
-
::
|
|
68
|
+
def parse_pubid(ref)
|
|
69
|
+
# A pubid from Relaton::Db (relaton#205) is used as it is.
|
|
70
|
+
return ref unless ref.is_a?(String)
|
|
71
|
+
|
|
72
|
+
::Pubid::Ieee::Identifier.parse ref
|
|
67
73
|
rescue StandardError
|
|
68
|
-
|
|
74
|
+
ref
|
|
69
75
|
end
|
|
70
76
|
end
|
|
71
77
|
end
|
|
@@ -44,6 +44,22 @@ module Relaton
|
|
|
44
44
|
nil
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
+
# An IEEE pubid keeps the other publishers in `publishers` (a joint
|
|
48
|
+
# development) or `copublisher` (a standard), not in the shared
|
|
49
|
+
# `copublishers`.
|
|
50
|
+
#
|
|
51
|
+
# @param pubid [Pubid::Ieee::Identifier]
|
|
52
|
+
# @return [Array<String>]
|
|
53
|
+
def copublishers(pubid)
|
|
54
|
+
pubid = pubid.identifiers.first if pubid.all_parts?
|
|
55
|
+
others = if pubid.respond_to?(:publishers) && pubid.publishers
|
|
56
|
+
pubid.publishers
|
|
57
|
+
elsif pubid.respond_to?(:copublisher)
|
|
58
|
+
pubid.copublisher
|
|
59
|
+
end
|
|
60
|
+
Array(others).map(&:to_s) - %w[IEEE AIEE]
|
|
61
|
+
end
|
|
62
|
+
|
|
47
63
|
# @param xml [String]
|
|
48
64
|
# @return [Relaton::Ieee::ItemData]
|
|
49
65
|
def from_xml(xml)
|
|
@@ -138,8 +138,8 @@ module Relaton
|
|
|
138
138
|
Renderer.new(publisher: "IEEE", number: "P802", part: "11aj", draft: "8.0", year: "2017")
|
|
139
139
|
when "IEEE P802.11ajD9.0, November 2017" # "IEEE P802-11aj/D9.0.2017"
|
|
140
140
|
Renderer.new(publisher: "IEEE", number: "P802", part: "11aj", draft: "9.0", year: "2017")
|
|
141
|
-
when "ISO/IEC/IEEE P29119-4-DISMay2013" # "ISO/IEC/IEEE DIS P29119-4.2013"
|
|
142
|
-
Renderer.new(publisher: "ISO/IEC/IEEE", stage: "DIS", number: "P29119", part: "4", year: "2013")
|
|
141
|
+
when "ISO/IEC/IEEE P29119-4-DISMay2013" # "ISO/IEC/IEEE DIS P29119-4.2013-05"
|
|
142
|
+
Renderer.new(publisher: "ISO/IEC/IEEE", stage: "DIS", number: "P29119", part: "4", year: "2013", month: "05")
|
|
143
143
|
when "IEEE-P15026-3-DIS-January 2015" # "IEEE DIS P15026-3.2015"
|
|
144
144
|
Renderer.new(publisher: "IEEE", stage: "DIS", number: "P15026", year: "2015")
|
|
145
145
|
when "ANSI/IEEE PC63.7/D rev17, December 2014" # "ANSI/IEEE PC63-7/D/REV-17.2014"
|
|
@@ -7,25 +7,27 @@ module Relaton
|
|
|
7
7
|
# IETF bibliography module
|
|
8
8
|
module Bibliography
|
|
9
9
|
class << self
|
|
10
|
-
# @param
|
|
10
|
+
# @param ref [String, Pubid::Ietf::Identifier] the IETF reference
|
|
11
|
+
# (e.g. "RFC 8341"), or its parse from Relaton::Db (relaton#205)
|
|
11
12
|
# @return [RelatonIetf::IetfBibliographicItem]
|
|
12
|
-
def search(
|
|
13
|
-
Scraper.scrape_page
|
|
13
|
+
def search(ref)
|
|
14
|
+
Scraper.scrape_page ref
|
|
14
15
|
end
|
|
15
16
|
|
|
16
|
-
# @param
|
|
17
|
+
# @param ref [String, Pubid::Ietf::Identifier] the IETF reference
|
|
18
|
+
# (e.g. "RFC 8341"), or its parse from Relaton::Db (relaton#205)
|
|
17
19
|
# @param year [String] the year the standard was published (optional)
|
|
18
20
|
# @param opts [Hash] options; restricted to :all_parts if all-parts
|
|
19
21
|
# reference is required
|
|
20
22
|
# @return [RelatonIetf::IetfBibliographicItem] Relaton of reference
|
|
21
|
-
def get(
|
|
22
|
-
Util.info "Fetching from Relaton repository ...", key:
|
|
23
|
-
result = search
|
|
23
|
+
def get(ref, _year = nil, _opts = {})
|
|
24
|
+
Util.info "Fetching from Relaton repository ...", key: ref.to_s
|
|
25
|
+
result = search ref
|
|
24
26
|
if result
|
|
25
27
|
docid = result.docidentifier.detect(&:primary) || result.docidentifier.first
|
|
26
|
-
Util.info "Found: `#{docid.content}`", key:
|
|
28
|
+
Util.info "Found: `#{docid.content}`", key: ref.to_s
|
|
27
29
|
else
|
|
28
|
-
Util.info "Not found.", key:
|
|
30
|
+
Util.info "Not found.", key: ref.to_s
|
|
29
31
|
end
|
|
30
32
|
result
|
|
31
33
|
end
|
data/lib/relaton/ietf/scraper.rb
CHANGED
|
@@ -15,17 +15,18 @@ module Relaton
|
|
|
15
15
|
# publishing their `index-v1` for released relatons, untouched.
|
|
16
16
|
IETF = "https://raw.githubusercontent.com/relaton/relaton-data-ietf/main/"
|
|
17
17
|
|
|
18
|
-
# @param
|
|
18
|
+
# @param ref [String, Pubid::Ietf::Identifier] a reference, or its parse
|
|
19
|
+
# from Relaton::Db (relaton#205), which is used as it is
|
|
19
20
|
# @return [Relaton::Ietf::ItemData, nil]
|
|
20
|
-
def scrape_page(
|
|
21
|
-
id = parse_id
|
|
21
|
+
def scrape_page(ref)
|
|
22
|
+
id = ref.is_a?(String) ? parse_id(ref.sub(/\AIETF\s+/, "")) : ref
|
|
22
23
|
return unless id
|
|
23
24
|
|
|
24
25
|
fetch_doc id
|
|
25
26
|
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
|
26
27
|
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
|
|
27
28
|
Net::ProtocolError, SocketError
|
|
28
|
-
raise Relaton::RequestError, "No document found for #{
|
|
29
|
+
raise Relaton::RequestError, "No document found for #{ref} reference"
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
private
|
|
@@ -24,7 +24,9 @@ module Relaton
|
|
|
24
24
|
raise Relaton::RequestError, e.message
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
# @param ref [String] the ISO standard Code to
|
|
27
|
+
# @param ref [String, Pubid::Iso::Identifier] the ISO standard Code to
|
|
28
|
+
# look up (e..g "ISO 9000"), or the parse that Relaton::Db routed with
|
|
29
|
+
# (relaton#205); a pubid is never mutated
|
|
28
30
|
# @param year [String, NilClass] the year the standard was published
|
|
29
31
|
# @param opts [Hash] options; restricted to :all_parts if all-parts
|
|
30
32
|
# @option opts [Boolean] :all_parts if all-parts reference is required
|
|
@@ -33,21 +35,21 @@ module Relaton
|
|
|
33
35
|
#
|
|
34
36
|
# @return [RelatonIsoBib::IsoBibliographicItem] Bibliographic item
|
|
35
37
|
def get(ref, year = nil, opts = {}) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity,Metrics/AbcSize
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
query_pubid = ::Pubid::Iso::Identifier.parse(code)
|
|
38
|
+
query_pubid = if ref.is_a?(String)
|
|
39
|
+
::Pubid::Iso::Identifier.parse(ref.gsub("\u2013", "-"))
|
|
40
|
+
else
|
|
41
|
+
ref
|
|
42
|
+
end
|
|
43
43
|
if year&.respond_to?(:to_i)
|
|
44
|
+
# Copy first: a caller's pubid is also its Db cache key.
|
|
45
|
+
query_pubid = query_pubid.class.from_hash(query_pubid.to_hash)
|
|
44
46
|
query_pubid.root.date = ::Pubid::Components::Date.new(year: year.to_s)
|
|
45
47
|
end
|
|
46
48
|
query_pubid = query_pubid.to_all_parts if opts[:all_parts]
|
|
47
49
|
Util.info "Fetching from Relaton repository ...", key: query_pubid.to_s
|
|
48
50
|
|
|
49
51
|
hits, missed_year_ids = isobib_search_filter(query_pubid, opts)
|
|
50
|
-
tip_ids = look_up_with_any_types_stages(hits, ref, opts)
|
|
52
|
+
tip_ids = look_up_with_any_types_stages(hits, ref.to_s, opts)
|
|
51
53
|
|
|
52
54
|
date_filter = opts[:publication_date_before] || opts[:publication_date_after]
|
|
53
55
|
if date_filter && !query_pubid.all_parts
|
|
@@ -31,13 +31,18 @@ module Relaton
|
|
|
31
31
|
HitCollection.new(refid).tap(&:search)
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
# @param
|
|
34
|
+
# @param ref [String, Pubid::Itu::Identifier] the ITU standard Code to
|
|
35
|
+
# look up, or its parse from Relaton::Db (relaton#205); #with_year
|
|
36
|
+
# copies, so the pubid is not changed
|
|
35
37
|
# @param year [String] the year the standard was published (optional)
|
|
36
38
|
# @param opts [Hash] options
|
|
37
39
|
# @return [Relaton::Bib::ItemData, nil]
|
|
38
|
-
def get(
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
def get(ref, year = nil, opts = {})
|
|
41
|
+
if ref.is_a? String
|
|
42
|
+
warn_incorrect_ref(ref)
|
|
43
|
+
ref = ::Pubid::Itu.parse(ref)
|
|
44
|
+
end
|
|
45
|
+
refid = with_year ref, year
|
|
41
46
|
|
|
42
47
|
ret = itubib_get1(refid)
|
|
43
48
|
return nil if ret.nil?
|
|
@@ -13,7 +13,8 @@ module Relaton
|
|
|
13
13
|
# the reference's series and number (a supplement is filed under its base
|
|
14
14
|
# number), so an edition and its amendments are returned together.
|
|
15
15
|
#
|
|
16
|
-
# @param [String]
|
|
16
|
+
# @param [String, Pubid::Jis::Identifier] ref JIS document reference; a
|
|
17
|
+
# pubid is never mutated
|
|
17
18
|
# @param [String, nil] year JIS document year
|
|
18
19
|
#
|
|
19
20
|
# @return [Relaton::Jis::HitCollection] search result
|
|
@@ -21,16 +22,21 @@ module Relaton
|
|
|
21
22
|
# @raise [Pubid::Errors::ParseError] when the reference is not a JIS
|
|
22
23
|
# identifier, so a malformed reference is not reported as "not found"
|
|
23
24
|
#
|
|
24
|
-
def search(
|
|
25
|
-
pubid = ::Pubid::Jis::Identifier.parse
|
|
26
|
-
|
|
25
|
+
def search(ref, year = nil)
|
|
26
|
+
pubid = ref.is_a?(String) ? ::Pubid::Jis::Identifier.parse(ref) : ref
|
|
27
|
+
if year && pubid.year.nil?
|
|
28
|
+
# Copy first: a caller's pubid is also its Db cache key.
|
|
29
|
+
pubid = pubid.class.from_hash(pubid.to_hash)
|
|
30
|
+
pubid.year = year.to_i
|
|
31
|
+
end
|
|
27
32
|
HitCollection.new pubid
|
|
28
33
|
end
|
|
29
34
|
|
|
30
35
|
#
|
|
31
36
|
# Get JIS document by reference
|
|
32
37
|
#
|
|
33
|
-
# @param [String] ref JIS document reference
|
|
38
|
+
# @param [String, Pubid::Jis::Identifier] ref JIS document reference, or
|
|
39
|
+
# the parse that Relaton::Db routed with (relaton#205)
|
|
34
40
|
# @param [String, nil] year JIS document year
|
|
35
41
|
# @param [Hash] opts options
|
|
36
42
|
# @option opts [Boolean] :all_parts return all parts of document
|
|
@@ -41,16 +47,21 @@ module Relaton
|
|
|
41
47
|
# identifier
|
|
42
48
|
#
|
|
43
49
|
def get(ref, year = nil, opts = {}) # rubocop:disable Metrics/AbcSize
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
50
|
+
if ref.is_a?(String)
|
|
51
|
+
query = ref.sub(/\s\((all parts|規格群)\)/, "")
|
|
52
|
+
opts[:all_parts] ||= !$1.nil?
|
|
53
|
+
else
|
|
54
|
+
opts[:all_parts] ||= ref.all_parts?
|
|
55
|
+
query = ref.all_parts? ? ref.identifiers.first : ref
|
|
56
|
+
end
|
|
57
|
+
Util.info "Fetching from webdesk.jsa.or.jp ...", key: ref.to_s
|
|
58
|
+
hits = search(query, year)
|
|
48
59
|
result = opts[:all_parts] ? hits.find_all_parts : hits.find
|
|
49
60
|
if result.is_a? Bib::ItemData
|
|
50
|
-
Util.info "Found: `#{result.docidentifier[0].content}`", key: ref
|
|
61
|
+
Util.info "Found: `#{result.docidentifier[0].content}`", key: ref.to_s
|
|
51
62
|
return result
|
|
52
63
|
end
|
|
53
|
-
hint result, ref, year
|
|
64
|
+
hint result, ref.to_s, year
|
|
54
65
|
end
|
|
55
66
|
|
|
56
67
|
#
|
|
@@ -7,18 +7,18 @@ module Relaton
|
|
|
7
7
|
#
|
|
8
8
|
# Search NIST documents by reference
|
|
9
9
|
#
|
|
10
|
-
# @param
|
|
10
|
+
# @param ref [String] reference
|
|
11
11
|
#
|
|
12
12
|
# @return [Relaton::Nist::HitCollection] search result
|
|
13
13
|
#
|
|
14
|
-
def search(
|
|
15
|
-
|
|
14
|
+
def search(ref, year = nil, opts = {})
|
|
15
|
+
query = ref.sub(/^NISTIR/, "NIST IR").sub(/\/Add/, " Add")
|
|
16
16
|
# pubid 2.x only recognizes the addendum marker with a trailing
|
|
17
17
|
# period, and only splits an uppercase part letter — canonicalize
|
|
18
18
|
# both ("800-38a Add" -> "800-38A Add.") so @reference parses to the
|
|
19
19
|
# same pubid the index/CSRC carry.
|
|
20
|
-
|
|
21
|
-
HitCollection.search
|
|
20
|
+
query = query.sub(/\bAdd\b\.?/i, "Add.").sub(/([0-9])([a-z])(?=\s+Add\.)/) { "#{$1}#{$2.upcase}" }
|
|
21
|
+
HitCollection.search query, year, opts
|
|
22
22
|
rescue OpenURI::HTTPError, SocketError, OpenSSL::SSL::SSLError => e
|
|
23
23
|
raise Relaton::RequestError, e.message
|
|
24
24
|
end
|
|
@@ -26,34 +26,38 @@ module Relaton
|
|
|
26
26
|
#
|
|
27
27
|
# Get NIST document by reference
|
|
28
28
|
#
|
|
29
|
-
# @param
|
|
29
|
+
# @param ref [String, Pubid::Nist::Identifier] the NIST standard Code
|
|
30
|
+
# to look up, or its parse from Relaton::Db (relaton#205)
|
|
30
31
|
# @param year [String] the year the standard was published (optional)
|
|
31
32
|
# @param opts [Hash] options
|
|
32
33
|
# @option opts [Boolean] :all_parts restricted to all parts
|
|
33
34
|
#
|
|
34
35
|
# @return [Relaton::Nist::ItemData, nil] bibliographic item
|
|
35
36
|
#
|
|
36
|
-
def get(
|
|
37
|
-
|
|
37
|
+
def get(ref, year = nil, opts = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
38
|
+
# The lookup below works on text, so a pubid from Relaton::Db is
|
|
39
|
+
# read back as its printed form; the pubid itself is not changed.
|
|
40
|
+
ref = ref.to_s unless ref.is_a?(String)
|
|
41
|
+
return fetch_ref_err(ref, year, []) if ref.match?(/\sEP$/)
|
|
38
42
|
|
|
39
|
-
/^(?<code2>[^(]+)(?:\((?<date2>\w+\s(?:\d{2},\s)?\d{4})\))?\s?\(?(?:(?<=\()(?<stage>(?:I|F|\d)PD))?/ =~
|
|
40
|
-
stage ||= /(?<=\.)PD-\w+(?=\.)/.match(
|
|
43
|
+
/^(?<code2>[^(]+)(?:\((?<date2>\w+\s(?:\d{2},\s)?\d{4})\))?\s?\(?(?:(?<=\()(?<stage>(?:I|F|\d)PD))?/ =~ ref
|
|
44
|
+
stage ||= /(?<=\.)PD-\w+(?=\.)/.match(ref)&.to_s
|
|
41
45
|
if code2
|
|
42
|
-
|
|
46
|
+
ref = code2.strip
|
|
43
47
|
opts[:date] = parse_date(date2, str: false) if date2
|
|
44
48
|
opts[:stage] = stage if stage
|
|
45
49
|
end
|
|
46
50
|
|
|
47
51
|
if year.nil?
|
|
48
|
-
/^(?<code1>[^:]+):(?<year1>[^:]+)$/ =~
|
|
52
|
+
/^(?<code1>[^:]+):(?<year1>[^:]+)$/ =~ ref
|
|
49
53
|
unless code1.nil?
|
|
50
|
-
|
|
54
|
+
ref = code1
|
|
51
55
|
year = year1
|
|
52
56
|
end
|
|
53
57
|
end
|
|
54
58
|
|
|
55
|
-
|
|
56
|
-
nistbib_get(
|
|
59
|
+
ref += "-1" if opts[:all_parts]
|
|
60
|
+
nistbib_get(ref, year, opts)
|
|
57
61
|
end
|
|
58
62
|
|
|
59
63
|
private
|
|
@@ -61,14 +65,14 @@ module Relaton
|
|
|
61
65
|
#
|
|
62
66
|
# Get NIST document by reference
|
|
63
67
|
#
|
|
64
|
-
# @param [String]
|
|
68
|
+
# @param [String] ref reference
|
|
65
69
|
# @param [String] year year
|
|
66
70
|
# @param [Hash] opts options
|
|
67
71
|
#
|
|
68
72
|
# @return [Relaton::Nist::ItemData, nil] bibliographic item
|
|
69
73
|
#
|
|
70
|
-
def nistbib_get(
|
|
71
|
-
result = nistbib_search_filter(
|
|
74
|
+
def nistbib_get(ref, year, opts)
|
|
75
|
+
result = nistbib_search_filter(ref, year, opts) || (return nil)
|
|
72
76
|
ret = nistbib_results_filter(result, year, opts)
|
|
73
77
|
if ret[:ret]
|
|
74
78
|
Util.info "Found: `#{ret[:ret].docidentifier.first.content}`", key: result.reference
|
|
@@ -153,14 +157,14 @@ module Relaton
|
|
|
153
157
|
#
|
|
154
158
|
# Get search results and filter them by code and year
|
|
155
159
|
#
|
|
156
|
-
# @param
|
|
160
|
+
# @param ref [String] reference
|
|
157
161
|
# @param year [String, nil] year
|
|
158
162
|
# @param opts [Hash] options
|
|
159
163
|
#
|
|
160
164
|
# @return [Relaton::Nist::HitCollection] hits collection
|
|
161
165
|
#
|
|
162
|
-
def nistbib_search_filter(
|
|
163
|
-
result = search(
|
|
166
|
+
def nistbib_search_filter(ref, year, opts)
|
|
167
|
+
result = search(ref, year, opts)
|
|
164
168
|
result.search_filter
|
|
165
169
|
end
|
|
166
170
|
|
|
@@ -16,16 +16,16 @@ module Relaton
|
|
|
16
16
|
OPTIONAL = %i[version stage part label].freeze
|
|
17
17
|
|
|
18
18
|
class << self
|
|
19
|
-
def search(
|
|
20
|
-
Util.info "Fetching from Relaton repository ...", key:
|
|
21
|
-
row = find_index_entry(
|
|
19
|
+
def search(ref, _year = nil, _opts = {}) # rubocop:disable Metrics/MethodLength
|
|
20
|
+
Util.info "Fetching from Relaton repository ...", key: ref.to_s
|
|
21
|
+
row = find_index_entry(ref)
|
|
22
22
|
unless row
|
|
23
|
-
Util.info "Not found.", key:
|
|
23
|
+
Util.info "Not found.", key: ref.to_s
|
|
24
24
|
return
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
uri = URI("#{ENDPOINT}#{row[:file]}")
|
|
28
|
-
parse_item(fetch_yaml(uri),
|
|
28
|
+
parse_item(fetch_yaml(uri), ref)
|
|
29
29
|
rescue SocketError, Errno::EINVAL, Errno::ECONNRESET, EOFError,
|
|
30
30
|
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
|
|
31
31
|
Net::ProtocolError, Net::ReadTimeout,
|
|
@@ -78,11 +78,11 @@ module Relaton
|
|
|
78
78
|
# by substring, so `OASIS amqp` resolved to some `amqp-core` record;
|
|
79
79
|
# v2 matches identifiers, so a partial name no longer resolves.
|
|
80
80
|
#
|
|
81
|
-
# @param
|
|
81
|
+
# @param ref [String] the reference as the caller wrote it
|
|
82
82
|
# @return [Hash, nil] the index row, or nil
|
|
83
83
|
#
|
|
84
|
-
def find_index_entry(
|
|
85
|
-
pubid = parse_ref
|
|
84
|
+
def find_index_entry(ref)
|
|
85
|
+
pubid = parse_ref ref
|
|
86
86
|
return unless pubid
|
|
87
87
|
|
|
88
88
|
rows = index.search(pubid)
|
|
@@ -111,12 +111,15 @@ module Relaton
|
|
|
111
111
|
# Rescuing here would collapse "this identifier is malformed" into "no
|
|
112
112
|
# such document", leaving a caller unable to tell them apart.
|
|
113
113
|
#
|
|
114
|
-
# @param
|
|
114
|
+
# @param ref [String, Pubid::Oasis::Identifier]
|
|
115
115
|
# @return [Pubid::Oasis::Identifier]
|
|
116
116
|
# @raise [Pubid::Errors::ParseError]
|
|
117
117
|
#
|
|
118
|
-
def parse_ref(
|
|
119
|
-
|
|
118
|
+
def parse_ref(ref)
|
|
119
|
+
# A parsed pubid comes from Relaton::Db (relaton#205); it is used as it is.
|
|
120
|
+
return ref unless ref.is_a?(String)
|
|
121
|
+
|
|
122
|
+
slug = ref.to_s.strip.sub(/\A#{Regexp.escape PREFIX}/i, "")
|
|
120
123
|
::Pubid::Oasis::Identifier.parse "#{PREFIX}#{slug}"
|
|
121
124
|
end
|
|
122
125
|
|
|
@@ -190,9 +193,9 @@ module Relaton
|
|
|
190
193
|
resp.body
|
|
191
194
|
end
|
|
192
195
|
|
|
193
|
-
def parse_item(yaml,
|
|
196
|
+
def parse_item(yaml, ref)
|
|
194
197
|
item = Item.from_yaml yaml
|
|
195
|
-
Util.info "Found: `#{item.docidentifier.first.content}`", key:
|
|
198
|
+
Util.info "Found: `#{item.docidentifier.first.content}`", key: ref.to_s
|
|
196
199
|
item.tap { |i| i.fetched = Date.today.to_s }
|
|
197
200
|
end
|
|
198
201
|
end
|