relaton-bipm 1.19.1 → 1.20.0

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: 6169158d13f03ec83666123ca52d0e87b7960ba13fe5b6d5051228c54158f93c
4
- data.tar.gz: 46236ffb5e1f875fd042dd89fe866251962a553497dd9a8a474edcd6aa18e2fa
3
+ metadata.gz: 98f4b8a04eb9738b1302ff84f91c11f5e604adfdefc2fdfac999279f4d62bf0d
4
+ data.tar.gz: 4e6dad8f65ca0472b24d178474b69a78fe20b3d784adbc1512d4c79aad576de0
5
5
  SHA512:
6
- metadata.gz: d1b01efea043f825d7e08dcecc6396e21b56c75ab0131dffd6b5e936ea10e185e9f8412ddf9c30fa21f64eaf9e97408da92e06fedc2a7cbb1d9da581151ab0ea
7
- data.tar.gz: 8cc33bc1d0b431ecd6d55c640ddcf5d715e640dfd2a926a5e2db5d72f442fefe93f527275f17236e2a815302cdb65ec9c47f71dd970b9d0eb708133765654d92
6
+ metadata.gz: d07764ecb8ffba9c394eb01fb17ec617c1209038390cd37e6035a897616e1f717b69ced0830da7d6b721733eeeb8d3ae503bb65a7efc9228142dd90852f1f665
7
+ data.tar.gz: a97d282c516026bd083a7ec534a0d1357e8eb4ab09f01495aff28e6be8fbabf78b071c422aa572690f12d5700d287ebb5cc2e34a23c7a1c88f041813834b7571
@@ -86,12 +86,16 @@ module RelatonBipm
86
86
  #
87
87
  def to_hash(embedded: false)
88
88
  hash = super
89
- hash["comment_period"] = comment_period.to_hash if comment_period
90
- hash["si_aspect"] = si_aspect if si_aspect
91
- hash["meeting_note"] = meeting_note if meeting_note
89
+ hash["ext"]["comment_period"] = comment_period.to_hash if comment_period
90
+ hash["ext"]["si_aspect"] = si_aspect if si_aspect
91
+ hash["ext"]["meeting_note"] = meeting_note if meeting_note
92
92
  hash
93
93
  end
94
94
 
95
+ def has_ext?
96
+ super || comment_period || si_aspect || meeting_note
97
+ end
98
+
95
99
  # @param prefix [String]
96
100
  # @return [String]
97
101
  def to_asciibib(prefix = "")
@@ -1,27 +1,31 @@
1
1
  module RelatonBipm
2
- class Committee
2
+ class Committee < RelatonBib::LocalizedString
3
+ ACRONYMS = YAML.load_file File.join(__dir__, "acronyms.yaml")
4
+
3
5
  # @return [String]
4
6
  attr_reader :acronym
5
7
 
6
8
  # @return [RelatonBib::LocalizedString]
7
9
  attr_reader :content
8
10
 
9
- # @param acronym [String]
10
- # @param content [RelatonBib::LocalisedString, String, nil]
11
- def initialize(acronym:, content: nil)
12
- acronyms = YAML.load_file File.join(__dir__, "acronyms.yaml")
13
- unless acronyms[acronym]
11
+ # @param [String] acronym
12
+ # @param [Hash] args
13
+ # @option args [RelatonBib::LocalisedString, String, nil] :content
14
+ # @option args [String, nil] :language
15
+ # @option args [String, nil] :script
16
+ def initialize(acronym:, **args)
17
+ unless ACRONYMS[acronym]
14
18
  Util.warn "Invalid acronym: `#{acronym}`. Allowed " \
15
- "values: `#{acronyms.map { |k, _v| k }.join '`, `'}`"
19
+ "values: `#{ACRONYMS.map { |k, _v| k }.join '`, `'}`"
16
20
  end
17
21
 
18
22
  @acronym = acronym
19
- @content = localized_content content, acronyms[acronym]
23
+ super(*localized_args(acronym, **args))
20
24
  end
21
25
 
22
26
  # @param builder [Nokogiri::XML::Builder]
23
27
  def to_xml(builder)
24
- builder.committee(acronym: acronym) { |b| content.to_xml b }
28
+ builder.committee(acronym: acronym) { |b| super b }
25
29
  end
26
30
 
27
31
  # @param prefix [String]
@@ -32,13 +36,13 @@ module RelatonBipm
32
36
  pref += "committee"
33
37
  out = count > 1 ? "#{pref}::\n" : ""
34
38
  out += "#{pref}.acronym:: #{acronym}\n"
35
- out + content.to_asciibib(pref)
39
+ out + super(pref)
36
40
  end
37
41
 
38
42
  # @return [Hash]
39
43
  def to_hash
40
44
  hash = { "acronym" => acronym }
41
- cnt = content.to_hash
45
+ cnt = super
42
46
  case cnt
43
47
  when Array then hash["variants"] = cnt
44
48
  when Hash then hash.merge! cnt
@@ -49,12 +53,14 @@ module RelatonBipm
49
53
 
50
54
  private
51
55
 
52
- def localized_content(cnt, acr)
53
- if cnt.is_a? String
54
- RelatonBib::LocalizedString.new cnt
55
- elsif (cnt.nil? || cnt.empty?) && acr && acr["en"]
56
- RelatonBib::LocalizedString.new(acr["en"], "en", "Latn")
57
- else cnt
56
+ def localized_args(accronym, **args)
57
+ if args[:content].is_a? String
58
+ [args[:content], args[:language], args[:script]]
59
+ elsif args[:content].nil?
60
+ lang = args[:language] || ACRONYMS.dig(acronym, "en") ? "en" : ACRONYMS[acronym]&.keys&.first
61
+ script = args[:script] || lang == "en" ? "Latn" : nil
62
+ [ACRONYMS.dig(accronym, lang), lang, script]
63
+ else [args[:content]]
58
64
  end
59
65
  end
60
66
  end
@@ -17,6 +17,7 @@ module RelatonBipm
17
17
 
18
18
  # project_group_hash_to_bib ret
19
19
  commentperiod_hash_to_bib ret
20
+ ret[:si_aspect] = args["ext"]["si_aspect"] if args.dig("ext", "si_aspect")
20
21
  ret
21
22
  end
22
23
 
@@ -42,7 +43,10 @@ module RelatonBipm
42
43
 
43
44
  # @param ret [Hash]
44
45
  def commentperiod_hash_to_bib(ret)
45
- ret[:comment_period] &&= CommentPeriond.new(**ret[:comment_period])
46
+ compr = ret.dig(:ext, :comment_period) || ret[:comment_period] # @TODO: remove ret[:comment_period] after all data is updated
47
+ return unless compr
48
+
49
+ ret[:comment_period] &&= CommentPeriond.new(**compr)
46
50
  end
47
51
 
48
52
  # @param ret [Hash]
@@ -69,17 +73,17 @@ module RelatonBipm
69
73
 
70
74
  # @param ret [Hash]
71
75
  def editorialgroup_hash_to_bib(ret) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
72
- return unless ret[:editorialgroup]
76
+ ed = ret.dig(:ext, :editorialgroup) || ret[:editorialgroup] # @TODO: remove ret[:editorialgroup] after all data is updated
77
+ return unless ed
73
78
 
74
- cmt = ret[:editorialgroup][:committee].map do |c|
79
+ cmt = ed[:committee].map do |c|
75
80
  if (vars = committee_variants c).any?
76
- content = RelatonBib::LocalizedString.new vars
77
- Committee.new acronym: c[:acronym], content: content
81
+ Committee.new acronym: c[:acronym], content: vars
78
82
  else
79
83
  Committee.new(**c)
80
84
  end
81
85
  end
82
- wg = RelatonBib.array(ret[:editorialgroup][:workgroup]).map do |w|
86
+ wg = RelatonBib.array(ed[:workgroup]).map do |w|
83
87
  w.is_a?(Hash) ? WorkGroup.new(**w) : WorkGroup.new(content: w)
84
88
  end
85
89
  ret[:editorialgroup] = EditorialGroup.new committee: cmt, workgroup: wg
@@ -98,9 +102,10 @@ module RelatonBipm
98
102
 
99
103
  # @param ret [Hash]
100
104
  def structuredidentifier_hash_to_bib(ret)
101
- ret[:structuredidentifier] &&= StructuredIdentifier.new(
102
- **ret[:structuredidentifier],
103
- )
105
+ struct_id = ret.dig(:ext, :structuredidentifier) || ret[:structuredidentifier] # @TODO: remove ret[:structuredidentifier] after all data is updated
106
+ return unless struct_id
107
+
108
+ ret[:structuredidentifier] = StructuredIdentifier.new(**struct_id)
104
109
  end
105
110
 
106
111
  def create_doctype(**args)
@@ -0,0 +1,111 @@
1
+ module RelatonBipm
2
+ module RawdataBipmMetrologia
3
+ class Affiliations
4
+ attr_reader :affiliations
5
+
6
+ #
7
+ # Initialize parser
8
+ #
9
+ # @param [Array<RelatonBib::Affiliation>] affiliations directory with affiliations
10
+ #
11
+ def initialize(affiliations)
12
+ @affiliations = affiliations
13
+ end
14
+
15
+ #
16
+ # Parse affiliations
17
+ #
18
+ # @return [RelatonBipm::RawdataBipmMetrologia::Affiliations] affiliations
19
+ #
20
+ def self.parse(dir)
21
+ affiliations = Dir["#{dir}/*.xml"].each_with_object([]) do |path, m|
22
+ doc = Nokogiri::XML(File.read(path, encoding: "UTF-8"))
23
+ doc.xpath("//aff").each do |aff|
24
+ m << parse_affiliation(aff) if aff.at("institution")
25
+ end
26
+ end.uniq { |a| a.organization.name.first.content }
27
+ new affiliations
28
+ end
29
+
30
+ #
31
+ # Parse affiliation organization
32
+ # https://github.com/relaton/relaton-data-bipm/issues/17#issuecomment-1367035444
33
+ #
34
+ # @param [Nokogiri::XML::Element] aff
35
+ #
36
+ # @return [RelatonBib::Affiliation] Organization name, country, division, street address
37
+ #
38
+ def self.parse_affiliation(aff)
39
+ text = aff.at("text()").text
40
+ return if text.include? "Permanent address:" || text.include?("1005 Southover Lane") ||
41
+ text == "Germany" || text.starts_with?("Guest") || text.starts_with?("Deceased") ||
42
+ text.include?("Author to whom any correspondence should be addressed")
43
+
44
+ args = {}
45
+ institution = aff.at('institution')
46
+ if institution
47
+ name = institution.text
48
+ return if name == "1005 Southover Lane"
49
+
50
+ args[:subdivision] = parse_division(aff)
51
+ args[:contact] = parse_address(aff)
52
+ else
53
+ # div, name, city, country = aff.xpath("text()").text.strip.split(", ")
54
+ # div, name = name, div if name.nil?
55
+ # args[:subdivision] = [RelatonBib::LocalizedString.new(div)] if div
56
+ # args[:contact] = [RelatonBib::Address.new(city: city, country: country)] if city && country
57
+ name = aff.text
58
+ end
59
+ args[:name] = [RelatonBib::LocalizedString.new(name)]
60
+ org = RelatonBib::Organization.new(**args)
61
+ RelatonBib::Affiliation.new(organization: org)
62
+ end
63
+
64
+ def self.parse_division(aff)
65
+ div = aff.xpath("text()[following-sibling::institution]").text.gsub(/^\W*|\W*$/, "")
66
+ return [] if div.empty?
67
+
68
+ [RelatonBib::LocalizedString.new(div)]
69
+ end
70
+
71
+ def self.parse_address(aff)
72
+ address = []
73
+ addr = aff.xpath("text()[preceding-sibling::institution]").text.gsub(/^\W*|\W*$/, "")
74
+ address << addr unless addr.empty?
75
+ country = aff.at('country')
76
+ address << country.text if country && !country.text.empty?
77
+ address = address.join(", ")
78
+ return [] if address.empty?
79
+
80
+ [RelatonBib::Address.new(formatted_address: address)]
81
+ end
82
+
83
+ def self.parse_elements(aff)
84
+ elements = aff.xpath("text()").text.strip.split(", ")
85
+ case elements.size
86
+ when 1 then { name: RelatonBib::LocalizedString.new(elements[0]) }
87
+ when 2
88
+ # name, country
89
+ { name: RelatonBib::LocalizedString.new(elements[0]),
90
+ contact: [RelatonBib::Address.new(formatted_address: elements[1])] }
91
+ when 3
92
+ # it can be name, country, city or name, city, country
93
+ # so use formatted_address instead of city and country
94
+ { name: RelatonBib::LocalizedString.new(elements[0]),
95
+ contact: RelatonBib::Address.new(formatted_address: elements[1, 2].join(", ")) }
96
+ end
97
+ end
98
+
99
+ #
100
+ # Find affiliation by organization name
101
+ #
102
+ # @param [Strign] text string with organization name in it
103
+ #
104
+ # @return [RelatonBib::Affiliation]
105
+ #
106
+ def find(text)
107
+ @affiliations.select { |a| text.include?(a.organization.name[0].content) }.sort.last
108
+ end
109
+ end
110
+ end
111
+ end
@@ -59,12 +59,9 @@ module RelatonBipm
59
59
  #
60
60
  # Parse volume, issue and page
61
61
  #
62
- # @return [Array<String>] array of volume, issue and page
62
+ # @return [String] volume issue page
63
63
  #
64
64
  def volume_issue_article
65
- # volume = @meta.at("./volume").text
66
- # issue = @meta.at("./issue").text
67
- # page = @doc.at("./front/article-meta/fpage")&.text || manuscript
68
65
  [@journal, @volume, @article].compact.join(" ")
69
66
  end
70
67
 
@@ -140,17 +137,53 @@ module RelatonBipm
140
137
  #
141
138
  # @return [Array<RelatonBib::Affiliation>] array of affiliations
142
139
  #
143
- def affiliation(contrib) # rubocop:disable Metrics/AbcSize
140
+ def affiliation(contrib)
144
141
  contrib.xpath("./xref[@ref-type='aff']").map do |x|
145
- a = @meta.at("./contrib-group/aff[@id='#{x[:rid]}']/label/following-sibling::node()")
146
- parts = a.text.split(", ")
147
- orgname = parts[0..-3].join(", ")
148
- city, country = parts[-2..]
149
- address = []
150
- address << RelatonBib::Address.new(city: city, country: country) if city && country
151
- org = RelatonBib::Organization.new name: orgname, contact: address
152
- RelatonBib::Affiliation.new organization: org
142
+ a = @meta.at("./contrib-group/aff[@id='#{x[:rid]}']") # /label/following-sibling::node()")
143
+ parse_affiliation a
144
+ end.compact
145
+ end
146
+
147
+ def parse_affiliation(aff)
148
+ text = aff.xpath("text()|sup|sub").to_xml.split(",").map(&:strip).reject(&:empty?).join(", ")
149
+ text = CGI::unescapeHTML(text)
150
+ return if text.include?("Permanent address:") || text == "Germany" ||
151
+ text.start_with?("Guest") || text.start_with?("Deceased") ||
152
+ text.include?("Author to whom any correspondence should be addressed")
153
+
154
+ args = {}
155
+ institution = aff.at('institution')
156
+ if institution
157
+ name = institution.text
158
+ return if name == "1005 Southover Lane"
159
+
160
+ args[:subdivision] = parse_division(aff)
161
+ args[:contact] = parse_address(aff)
162
+ else
163
+ name = text
153
164
  end
165
+ args[:name] = [RelatonBib::LocalizedString.new(name)]
166
+ org = RelatonBib::Organization.new(**args)
167
+ RelatonBib::Affiliation.new(organization: org)
168
+ end
169
+
170
+ def parse_division(aff)
171
+ div = aff.xpath("text()[following-sibling::institution]").text.gsub(/^\W*|\W*$/, "")
172
+ return [] if div.empty?
173
+
174
+ [RelatonBib::LocalizedString.new(div)]
175
+ end
176
+
177
+ def parse_address(aff)
178
+ address = []
179
+ addr = aff.xpath("text()[preceding-sibling::institution]").text.gsub(/^\W*|\W*$/, "")
180
+ address << addr unless addr.empty?
181
+ country = aff.at('country')
182
+ address << country.text if country && !country.text.empty?
183
+ address = address.join(", ")
184
+ return [] if address.empty?
185
+
186
+ [RelatonBib::Address.new(formatted_address: address)]
154
187
  end
155
188
 
156
189
  #
@@ -173,20 +206,20 @@ module RelatonBipm
173
206
  #
174
207
  # @return [Array<RelatonBib::Forename>] array of forenames
175
208
  #
176
- def forename(given_name) # rubocop:disable Metrics/MethodLength
177
- return [] unless given_name
209
+ # def forename(given_name) # rubocop:disable Metrics/MethodLength
210
+ # return [] unless given_name
178
211
 
179
- given_name.text.scan(/(\w+)(?:\s(\w)(?:\s|$))?/).map do |nm, int|
180
- if nm.size == 1
181
- name = nil
182
- init = nm
183
- else
184
- name = nm
185
- init = int
186
- end
187
- RelatonBib::Forename.new(content: name, language: ["en"], script: ["Latn"], initial: init)
188
- end
189
- end
212
+ # given_name.text.scan(/(\w+)(?:\s(\w)(?:\s|$))?/).map do |nm, int|
213
+ # if nm.size == 1
214
+ # name = nil
215
+ # init = nm
216
+ # else
217
+ # name = nm
218
+ # init = int
219
+ # end
220
+ # RelatonBib::Forename.new(content: name, language: ["en"], script: ["Latn"], initial: init)
221
+ # end
222
+ # end
190
223
 
191
224
  #
192
225
  # Parse date
@@ -29,8 +29,9 @@ module RelatonBipm
29
29
  # Fetch articles from rawdata-bipm-metrologia and save to files
30
30
  #
31
31
  def fetch_articles # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
32
+ # aff = Affiliations.parse DIR
32
33
  Dir["#{DIR}/**/*.xml"].each do |path|
33
- item = ArticleParser.parse path
34
+ item = ArticleParser.parse path # , aff
34
35
  file = "#{item.docidentifier.first.id.downcase.tr(' ', '-')}.#{@data_fetcher.ext}"
35
36
  out_path = File.join(@data_fetcher.output, file)
36
37
  key = Id.new.parse(item.docidentifier.first.id).to_hash
@@ -1,3 +1,3 @@
1
1
  module RelatonBipm
2
- VERSION = "1.19.1".freeze
2
+ VERSION = "1.20.0".freeze
3
3
  end
@@ -58,12 +58,9 @@ module RelatonBipm
58
58
 
59
59
  cm = eg.xpath("committee").map do |c|
60
60
  vars = variants c
61
- cnt = if vars.any?
62
- RelatonBib::LocalizedString.new vars
63
- else
64
- RelatonBib::LocalizedString.new c.text, c[:language], c[:script]
65
- end
66
- Committee.new acronym: c[:acronym], content: cnt
61
+ cnt = vars.any? ? vars : c.text
62
+ args = c.to_h.transform_keys(&:to_sym).select { |k, _| %i[language script locale].include?(k) }
63
+ Committee.new acronym: c[:acronym], content: cnt, **args
67
64
  end
68
65
  wg = eg.xpath("workgroup").map do |w|
69
66
  WorkGroup.new content: w.text, acronym: w[:acronym]
data/relaton_bipm.gemspec CHANGED
@@ -35,7 +35,7 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
35
35
  spec.add_dependency "faraday", "~> 2.7.0"
36
36
  spec.add_dependency "mechanize", "~> 2.10"
37
37
  spec.add_dependency "parslet", "~> 2.0.0"
38
- spec.add_dependency "relaton-bib", "~> 1.19.0"
38
+ spec.add_dependency "relaton-bib", "~> 1.20.0"
39
39
  spec.add_dependency "relaton-index", "~> 0.2.2"
40
40
  spec.add_dependency "rubyzip", "~> 2.3.0"
41
41
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relaton-bipm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.19.1
4
+ version: 1.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-31 00:00:00.000000000 Z
11
+ date: 2024-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 1.19.0
61
+ version: 1.20.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 1.19.0
68
+ version: 1.20.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: relaton-index
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -135,6 +135,7 @@ files:
135
135
  - lib/relaton_bipm/hash_converter.rb
136
136
  - lib/relaton_bipm/id_parser.rb
137
137
  - lib/relaton_bipm/processor.rb
138
+ - lib/relaton_bipm/rawdata_bipm_metrologia/affiliations.rb
138
139
  - lib/relaton_bipm/rawdata_bipm_metrologia/article_parser.rb
139
140
  - lib/relaton_bipm/rawdata_bipm_metrologia/fetcher.rb
140
141
  - lib/relaton_bipm/structured_identifier.rb
@@ -149,7 +150,7 @@ licenses:
149
150
  metadata:
150
151
  homepage_uri: https://github.com/relaton/relaton-bipm
151
152
  source_code_uri: https://github.com/relaton/relaton-bipm
152
- post_install_message:
153
+ post_install_message:
153
154
  rdoc_options: []
154
155
  require_paths:
155
156
  - lib
@@ -165,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
166
  version: '0'
166
167
  requirements: []
167
168
  rubygems_version: 3.3.27
168
- signing_key:
169
+ signing_key:
169
170
  specification_version: 4
170
171
  summary: 'RelatonBipm: retrieve BIPM Standards for bibliographic use using the BibliographicItem
171
172
  model'