relaton-doi 1.14.2 → 1.14.4

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: d39addcfe400051b6cfadb759265bee674ace775bff92dab29a1c7f80891cd48
4
- data.tar.gz: e24fa98bbfbff44bcb9b6b200c79750fe2f72ece457f67162a62324742a56cee
3
+ metadata.gz: 4184d182bd51c7b61a50ae43d52bd95ddd73024defb5ca8ee96641ca7ae4b13b
4
+ data.tar.gz: 519e7864a1ddea5cc3a74569848e08ba0951d61877b0e9c9262c76b69afb46c5
5
5
  SHA512:
6
- metadata.gz: 33bf3eabe2d1786be51d05960ad0aff732dc3ebceed3bde02979cb6e01790c2c2f65f221ca5d1f1567b73be3b28ceab9bb2ec4b8303e7165881a7c9d88b3f9ae
7
- data.tar.gz: d3e180ade463b3e94785c271dd795b440b645426cecf914a6684b67eadd2313b22155eb31860d4602407c38e8266b031c962cd7affad9947c98361553109a4c8
6
+ metadata.gz: b544c06393cd74c073cc1c815e12646ef8d06b3f6fcbee464547d21416617d707ea33ffd370bb69c0aba94d6feda816bc78fa0cb36bc7ac5960ed90e5bc4304f
7
+ data.tar.gz: bd11ec0a75b525c6d34a0b922a1a2b64784a2944f3fd8e49f5756493160b25a7da7078c70ac2b853f7bf8a19ec3e941eb3597327293ccdca6a74429140bb2f55
@@ -5,6 +5,7 @@ name: rake
5
5
  on:
6
6
  push:
7
7
  branches: [ master, main ]
8
+ tags: [ v* ]
8
9
  pull_request:
9
10
 
10
11
  jobs:
@@ -10,8 +10,9 @@ on:
10
10
  Next release version. Possible values: x.y.z, major, minor, patch or pre|rc|etc
11
11
  required: true
12
12
  default: 'skip'
13
- push:
14
- tags: [ v* ]
13
+ repository_dispatch:
14
+ types: [ do-release ]
15
+
15
16
 
16
17
  jobs:
17
18
  release:
data/.gitignore CHANGED
@@ -6,6 +6,7 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ /vendor/
9
10
 
10
11
  # rspec failure tracking
11
12
  .rspec_status
data/.rubocop.yml CHANGED
@@ -7,6 +7,6 @@ require: rubocop-rails
7
7
  inherit_from:
8
8
  - https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
9
9
  AllCops:
10
- TargetRubyVersion: 2.5
10
+ TargetRubyVersion: 2.7
11
11
  Rails:
12
12
  Enabled: false
data/Gemfile CHANGED
@@ -5,8 +5,13 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in relaton-doi.gemspec
6
6
  gemspec
7
7
 
8
+ gem "debug"
9
+ gem "equivalent-xml", "~> 0.6"
8
10
  gem "rake", "~> 13.0"
9
-
10
11
  gem "rspec", "~> 3.0"
11
-
12
12
  gem "rubocop", "~> 1.7"
13
+ gem "rubocop-performance"
14
+ gem "rubocop-rails"
15
+ gem "simplecov"
16
+ gem "vcr"
17
+ gem "webmock"
@@ -1,53 +1,6 @@
1
1
  module RelatonDoi
2
- class Crossref
3
- TYPES = {
4
- "book-chapter" => "inbook",
5
- "book-part" => "inbook",
6
- "book-section" => "inbook",
7
- "book-series" => "book",
8
- "book-set" => "book",
9
- "book-track" => "inbook",
10
- "component" => "misc",
11
- "database" => "dataset",
12
- "dissertation" => "thesis",
13
- "edited-book" => "book",
14
- "grant" => "misc",
15
- "journal-article" => "article",
16
- "journal-issue" => "journal",
17
- "journal-volume" => "journal",
18
- "monograph" => "book",
19
- "other" => "misc",
20
- "peer-review" => "article",
21
- "posted-content" => "social_media",
22
- "proceedings-article" => "inproceedings",
23
- "proceedings-series" => "proceedings",
24
- "reference-book" => "book",
25
- "reference-entry" => "inbook",
26
- "report-component" => "techreport",
27
- "report-series" => "techreport",
28
- "report" => "techreport",
29
- }.freeze
30
-
31
- REALATION_TYPES = {
32
- "is-preprint-of" => "reprintOf",
33
- "is-review-of" => "reviewOf",
34
- "has-review" => "hasReview",
35
- "is-identical-to" => "identicalTo", # ?
36
- "is-supplement-to" => "complements",
37
- }.freeze
38
-
39
- #
40
- # Get a document by DOI from the CrossRef API.
41
- #
42
- # @param [String] doi The DOI.
43
- #
44
- # @return [RelatonBib::BibliographicItem, RelatonIetf::IetfBibliographicItem,
45
- # RelatonBipm::BipmBibliographicItem, RelatonIeee::IeeeBibliographicItem,
46
- # RelatonNist::NistBibliographicItem] The bibitem.
47
- #
48
- def self.get(doi)
49
- new.get doi
50
- end
2
+ module Crossref
3
+ extend self
51
4
 
52
5
  #
53
6
  # Get a document by DOI from the CrossRef API.
@@ -61,387 +14,21 @@ module RelatonDoi
61
14
  def get(doi)
62
15
  warn "[relaton-doi] [\"#{doi}\"] fetching..."
63
16
  id = doi.sub(%r{^doi:}, "")
64
- resp = Serrano.works ids: id
65
- @message = resp[0]["message"]
66
- warn "[relaton-doi] [\"#{doi}\"] found #{@message['DOI']}"
67
- create_bibitem @message["DOI"], bibitem_hash
68
- end
69
-
70
- #
71
- # Create a bibitem from the bibitem hash.
72
- #
73
- # @param [String] doi The DOI.
74
- # @param [Hash] bibitem The bibitem hash.
75
- #
76
- # @return [RelatonBib::BibliographicItem, RelatonIetf::IetfBibliographicItem,
77
- # RelatonBipm::BipmBibliographicItem, RelatonIeee::IeeeBibliographicItem,
78
- # RelatonNist::NistBibliographicItem] The bibitem.
79
- #
80
- # @raise [RelatonDoi::Error] if the document type is not supported.
81
- #
82
- def create_bibitem(doi, bibitem) # rubocop:disable Metrics/CyclomaticComplexity
83
- # case @message["institution"]&.first&.fetch("acronym")&.first
84
- case doi
85
- when /\/nist/ then RelatonNist::NistBibliographicItem.new(**bibitem)
86
- when /\/rfc\d+/ then RelatonIetf::IetfBibliographicItem.new(**bibitem)
87
- when /\/0026-1394\// then RelatonBipm::BipmBibliographicItem.new(**bibitem)
88
- # when "ISO" then RelatonIso::IsoBibliographicItem.new(**bibitem)
89
- # when "W3C" then RelatonW3c::W3cBibliographicItem.new(**bibitem)
90
- when /\/ieee/ then RelatonIeee::IeeeBibliographicItem.new(**bibitem)
91
- else RelatonBib::BibliographicItem.new(**bibitem)
92
- end
93
- end
94
-
95
- #
96
- # Create a bibitem hash from the message hash.
97
- #
98
- # @return [Hash] The bibitem hash.
99
- #
100
- def bibitem_hash # rubocop:disable Metrics/MethodLength
101
- {
102
- type: parse_type,
103
- fetched: Date.today.to_s,
104
- title: create_title,
105
- docid: create_docid,
106
- date: create_date,
107
- link: create_link,
108
- abstract: create_abstract,
109
- contributor: create_contributors,
110
- doctype: @message["type"],
111
- place: create_place,
112
- relation: create_relation,
113
- extent: create_extent,
114
- series: create_series,
115
- }
116
- end
117
-
118
- #
119
- # Parse the document type.
120
- #
121
- # @return [String] The document type.
122
- #
123
- def parse_type
124
- TYPES[@message["type"]] || @message["type"]
125
- end
126
-
127
- #
128
- # Create a title and a subtitle from the message hash.
129
- #
130
- # @return [Array<RelatonBib::TypedTitleString>] The title and subtitle.
131
- #
132
- def create_title
133
- @message["title"].map do |t|
134
- RelatonBib::TypedTitleString.new(
135
- type: "main", content: t, language: "en", script: "Latn",
136
- )
137
- end + @message["subtitle"].map do |t|
138
- RelatonBib::TypedTitleString.new(
139
- type: "subtitle", content: t, language: "en", script: "Latn",
140
- )
141
- end
142
- end
143
-
144
- #
145
- # Create a docid from the message hash.
146
- #
147
- # @return [Array<RelatonBib::DocumentIdentifier>] The docid.
148
- #
149
- def create_docid
150
- %w[DOI ISBN].each_with_object([]) do |type, obj|
151
- id = @message[type].is_a?(Array) ? @message[type].first : @message[type]
152
- next unless id
153
-
154
- primary = type == "DOI"
155
- obj << RelatonBib::DocumentIdentifier.new(type: type, id: id, primary: primary)
156
- end
17
+ message = get_by_id id
18
+ warn "[relaton-doi] [\"#{doi}\"] found #{message['DOI']}"
19
+ Parser.parse message
157
20
  end
158
21
 
159
22
  #
160
- # Create dates from the message hash.
161
- #
162
- # @return [Array<RelatonBib::BibliographicDate>] The dates.
163
- #
164
- def create_date
165
- %w[created issued published approved].each_with_object([]) do |type, obj|
166
- next unless @message[type]
167
-
168
- on = @message[type]["date-parts"][0].map { |d| d.to_s.rjust(2, "0") }.join "-"
169
- obj << RelatonBib::BibliographicDate.new(type: type, on: on)
170
- end
171
- end
172
-
173
- #
174
- # Create a link from the message hash.
175
- #
176
- # @return [Array<RelatonBib::TypedUri>] The link.
177
- #
178
- def create_link
179
- links = []
180
- if @message["URL"]
181
- links << RelatonBib::TypedUri.new(type: "DOI", content: @message["URL"])
182
- end
183
- return links unless @message["link"]&.any?
184
-
185
- link = @message["link"].first
186
- if link["URL"].match?(/\.pdf$/)
187
- links << RelatonBib::TypedUri.new(type: "pdf", content: link["URL"])
188
- end
189
- links
190
- end
191
-
192
- #
193
- # Create an abstract from the message hash.
194
- #
195
- # @return [Array<RelatonBib::FormattedString>] The abstract.
196
- #
197
- def create_abstract
198
- return [] unless @message["abstract"]
199
-
200
- content = @message["abstract"]
201
- abstract = RelatonBib::FormattedString.new(
202
- content: content, language: "en", script: "Latn", format: "text/html",
203
- )
204
- [abstract]
205
- end
206
-
207
- #
208
- # Create contributors from the message hash.
209
- #
210
- # @return [Array<RelatonBib::ContributionInfo>] The contributors.
211
- #
212
- def create_contributors # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
213
- contribs = %w[author editor translator].each_with_object([]) do |type, obj|
214
- @message[type]&.each do |contrib|
215
- obj << contributor(person(contrib), type)
216
- end
217
- end
218
- contribs << contributor(org_publisher, "publisher")
219
- end
220
-
221
- #
222
- # Cerate an organization publisher from the message hash.
223
- #
224
- # @return [RelatonBib::Organization] The organization.
225
- #
226
- def org_publisher
227
- pbr = @message["institution"]&.detect do |i|
228
- @message["publisher"].include?(i["name"]) ||
229
- i["name"].include?(@message["publisher"])
230
- end
231
- a = pbr["acronym"]&.first if pbr
232
- RelatonBib::Organization.new name: @message["publisher"], abbreviation: a
233
- end
234
-
235
- #
236
- # Create contributor from an entity and a role type.
237
- #
238
- # @param [RelatonBib::Person, RelatonBib::Organization] entity The entity.
239
- # @param [String] type The role type.
240
- #
241
- # @return [RelatonBib::ContributionInfo] The contributor.
242
- #
243
- def contributor(entity, type)
244
- RelatonBib::ContributionInfo.new(entity: entity, role: [type: type])
245
- end
246
-
247
- #
248
- # Create a person from a person hash.
249
- #
250
- # @param [Hash] person The person hash.
251
- #
252
- # @return [RelatonBib::Person] The person.
253
- #
254
- def person(person)
255
- RelatonBib::Person.new(
256
- name: person_name(person), affiliation: affiliation(person),
257
- identifier: person_id(person)
258
- )
259
- end
260
-
261
- #
262
- # Create person affiliations from a person hash.
263
- #
264
- # @param [Hash] person The person hash.
265
- #
266
- # @return [Array<RelatonBib::Affiliation>] The affiliations.
267
- #
268
- def affiliation(person)
269
- (person["affiliation"] || []).map do |a|
270
- org = RelatonBib::Organization.new(name: a["name"])
271
- RelatonBib::Affiliation.new organization: org
272
- end
273
- end
274
-
275
- #
276
- # Create a person full name from a person hash.
277
- #
278
- # @param [Hash] person The person hash.
279
- #
280
- # @return [RelatonBib::FullName] The full name.
281
- #
282
- def person_name(person)
283
- sn = RelatonBib::LocalizedString.new(person["family"], "en", "Latn")
284
- RelatonBib::FullName.new(
285
- surname: sn, forename: forename(person), addition: nameaddition(person),
286
- completename: completename(person), prefix: nameprefix(person)
287
- )
288
- end
289
-
290
- #
291
- # Create a person name prefix from a person hash.
292
- #
293
- # @param [Hash] person The person hash.
294
- #
295
- # @return [Array<RelatonBib::LocalizedString>] The name prefix.
296
- #
297
- def nameprefix(person)
298
- return [] unless person["prefix"]
299
-
300
- [RelatonBib::LocalizedString.new(person["prefix"], "en", "Latn")]
301
- end
302
-
303
- #
304
- # Create a complete name from a person hash.
305
- #
306
- # @param [Hash] person The person hash.
307
- #
308
- # @return [RelatonBib::LocalizedString] The complete name.
309
- #
310
- def completename(person)
311
- return unless person["name"]
312
-
313
- RelatonBib::LocalizedString.new(person["name"], "en", "Latn")
314
- end
315
-
316
- #
317
- # Create a forename from a person hash.
318
- #
319
- # @param [Hash] person The person hash.
320
- #
321
- # @return [Array<RelatonBib::LocalizedString>] The forename.
322
- #
323
- def forename(person)
324
- return [] unless person["given"]
325
-
326
- [RelatonBib::Forename.new(content: person["given"], language: "en", script: "Latn")]
327
- end
328
-
329
- #
330
- # Create an addition from a person hash.
331
- #
332
- # @param [Hash] person The person hash.
333
- #
334
- # @return [Array<RelatonBib::LocalizedString>] The addition.
335
- #
336
- def nameaddition(person)
337
- return [] unless person["suffix"]
338
-
339
- [RelatonBib::LocalizedString.new(person["suffix"], "en", "Latn")]
340
- end
341
-
342
- #
343
- # Create a person identifier from a person hash.
344
- #
345
- # @param [Hash] person The person hash.
346
- #
347
- # @return [Array<RelatonBib::PersonIdentifier>] The person identifier.
348
- #
349
- def person_id(person)
350
- return [] unless person["ORCID"]
351
-
352
- [RelatonBib::PersonIdentifier.new("orcid", person["ORCID"])]
353
- end
354
-
355
- #
356
- # Create a place from the message hash.
357
- #
358
- # @return [Array<RelatonBib::Place>] The place.
359
- #
360
- def create_place
361
- return [] unless @message["publisher-location"]
362
-
363
- city, rg = @message["publisher-location"].split(", ")
364
- region = RelatonBib::Place::RegionType.new(name: rg)
365
- [RelatonBib::Place.new(city: city, region: [region])]
366
- end
367
-
368
- #
369
- # Crerate relations from the message hash.
370
- #
371
- # @return [Array<RelatonBib::DocumentRelation>] The relations.
372
- #
373
- def create_relation # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
374
- rels = []
375
- @message["container-title"]&.each do |ct|
376
- contrib = included_in_editors(ct)
377
- bib = RelatonBib::BibliographicItem.new(title: [content: ct], contributor: contrib)
378
- rels << RelatonBib::DocumentRelation.new(type: "includedIn", bibitem: bib)
379
- end
380
- @message["relation"].each_with_object(rels) do |(k, v), a|
381
- fref = RelatonBib::FormattedRef.new(content: v["id"])
382
- bib = create_bibitem v["id"], formattedref: fref
383
- type = REALATION_TYPES[k] || k
384
- a << RelatonBib::DocumentRelation.new(type: type, bibitem: bib)
385
- end
386
- end
387
-
388
- #
389
- # Fetch included in editors.
390
- #
391
- # @param [String] title container-title
392
- #
393
- # @return [Array<RelatonBib::ContributionInfo>] The editors contribution info.
394
- #
395
- def included_in_editors(title)
396
- item = fetch_included_in title
397
- return [] unless item
398
-
399
- item["editor"].map { |e| contributor(person(e), "editor") }
400
- end
401
-
402
- #
403
- # Fetch included in relation.
404
- #
405
- # @param [String] title container-title
406
- #
407
- # @return [Hash] The included in relation item.
408
- #
409
- def fetch_included_in(title) # rubocop:disable Metrics/AbcSize
410
- year = (@message["published"] || @message["approved"])["date-parts"][0][0]
411
- query = "#{title}, #{@message['publisher']}, #{@message['publisher-location']}, #{year}"
412
- resp = Faraday.get %{http://api.crossref.org/works?query.bibliographic="#{query}"&rows=5&filter=type:book}
413
- json = JSON.parse resp.body
414
- json["message"]["items"].detect { |i| i["title"].include?(title) && i["editor"] }
415
- end
416
-
417
- #
418
- # Create an extent from the message hash.
419
- #
420
- # @return [Array<RelatonBib::Locality>] The extent.
421
- #
422
- def create_extent # rubocop:disable Metrics/AbcSize
423
- extent = []
424
- extent << RelatonBib::Locality.new("volume", @message["volume"]) if @message["volume"]
425
- extent << RelatonBib::Locality.new("issue", @message["issue"]) if @message["issue"]
426
- if @message["page"]
427
- from, to = @message["page"].split("-")
428
- extent << RelatonBib::Locality.new("page", from, to)
429
- end
430
- extent.any? ? [RelatonBib::LocalityStack.new(extent)] : []
431
- end
432
-
23
+ # Get a document by DOI from the CrossRef API.
433
24
  #
434
- # Create a series from the message hash.
25
+ # @param [String] id The DOI.
435
26
  #
436
- # @return [Arrey<RelatonBib::Series>] The series.
27
+ # @return [Hash] The document.
437
28
  #
438
- def create_series
439
- return [] unless @message["container-title"]
440
-
441
- @message["container-title"].map do |ct|
442
- title = RelatonBib::TypedTitleString.new content: ct
443
- RelatonBib::Series.new title: title
444
- end
29
+ def get_by_id(id)
30
+ resp = Serrano.works ids: id
31
+ resp[0]["message"]
445
32
  end
446
33
  end
447
34
  end