bolognese 0.8.5 → 0.8.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +10 -9
- data/README.md +15 -1
- data/lib/bolognese.rb +2 -0
- data/lib/bolognese/bibtex.rb +57 -1
- data/lib/bolognese/citeproc.rb +116 -0
- data/lib/bolognese/codemeta.rb +9 -1
- data/lib/bolognese/crossref.rb +20 -0
- data/lib/bolognese/datacite.rb +9 -1
- data/lib/bolognese/datacite_json.rb +9 -1
- data/lib/bolognese/datacite_utils.rb +1 -1
- data/lib/bolognese/metadata.rb +185 -1
- data/lib/bolognese/ris.rb +117 -0
- data/lib/bolognese/schema_org.rb +8 -0
- data/lib/bolognese/utils.rb +84 -17
- data/lib/bolognese/version.rb +1 -1
- data/resources/kernel-3/metadata.xsd +3 -3
- data/spec/bibtex_spec.rb +34 -0
- data/spec/citeproc_spec.rb +48 -0
- data/spec/codemeta_spec.rb +33 -3
- data/spec/crossref_spec.rb +80 -2
- data/spec/datacite_json_spec.rb +28 -12
- data/spec/datacite_spec.rb +72 -0
- data/spec/datacite_utils_spec.rb +1 -1
- data/spec/fixtures/citeproc.json +21 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_Codemeta/get_metadata_as_citeproc/maremma.yml +100 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_Codemeta/get_metadata_as_ris/BlogPosting.yml +100 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_Codemeta/get_metadata_as_ris/maremma.yml +100 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata_as_citeproc/journal_article.yml +723 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata_as_citeproc/with_pages.yml +370 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata_as_ris/journal_article.yml +723 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata_as_ris/with_pages.yml +370 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_Datacite/get_metadata/Citeproc_JSON.yml +173 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_Datacite/get_metadata_as_citeproc/BlogPosting.yml +155 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_Datacite/get_metadata_as_citeproc/Dataset.yml +173 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_Datacite/get_metadata_as_ris/BlogPosting.yml +155 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_Datacite/get_metadata_as_ris/Dataset.yml +173 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_Metadata/read/datacite.yml +173 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_Metadata/write/datacite_to_bibtex.yml +173 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_SchemaOrg/get_metadata_as_citeproc/BlogPosting.yml +653 -0
- data/spec/fixtures/vcr_cassettes/Bolognese_SchemaOrg/get_metadata_as_ris/BlogPosting.yml +653 -0
- data/spec/schema_org_spec.rb +30 -0
- data/spec/utils_spec.rb +50 -0
- metadata +22 -2
@@ -0,0 +1,117 @@
|
|
1
|
+
module Bolognese
|
2
|
+
class Ris < Metadata
|
3
|
+
|
4
|
+
BIB_TO_SO_TRANSLATIONS = {
|
5
|
+
"article" => "ScholarlyArticle"
|
6
|
+
}
|
7
|
+
|
8
|
+
SO_TO_BIB_TRANSLATIONS = {
|
9
|
+
"Article" => "article",
|
10
|
+
"AudioObject" => "misc",
|
11
|
+
"Blog" => "misc",
|
12
|
+
"BlogPosting" => "article",
|
13
|
+
"Collection" => "misc",
|
14
|
+
"CreativeWork" => "misc",
|
15
|
+
"DataCatalog" => "misc",
|
16
|
+
"Dataset" => "misc",
|
17
|
+
"Event" => "misc",
|
18
|
+
"ImageObject" => "misc",
|
19
|
+
"Movie" => "misc",
|
20
|
+
"PublicationIssue" => "misc",
|
21
|
+
"ScholarlyArticle" => "article",
|
22
|
+
"Service" => "misc",
|
23
|
+
"SoftwareSourceCode" => "misc",
|
24
|
+
"VideoObject" => "misc",
|
25
|
+
"WebPage" => "misc",
|
26
|
+
"WebSite" => "misc"
|
27
|
+
}
|
28
|
+
|
29
|
+
BIB_TO_CP_TRANSLATIONS = {
|
30
|
+
"article" => "article-journal"
|
31
|
+
}
|
32
|
+
|
33
|
+
def initialize(string: nil)
|
34
|
+
@raw = string
|
35
|
+
end
|
36
|
+
|
37
|
+
def metadata
|
38
|
+
@metadata ||= raw.present? ? BibTeX.parse(raw).first : {}
|
39
|
+
end
|
40
|
+
|
41
|
+
def exists?
|
42
|
+
metadata.present?
|
43
|
+
end
|
44
|
+
|
45
|
+
def valid?
|
46
|
+
bibtex.present?
|
47
|
+
end
|
48
|
+
|
49
|
+
def type
|
50
|
+
BIB_TO_SO_TRANSLATIONS[metadata.type.to_s] || "ScholarlyArticle"
|
51
|
+
end
|
52
|
+
|
53
|
+
def citeproc_type
|
54
|
+
BIB_TO_CP_TRANSLATIONS[metadata.type.to_s] || "misc"
|
55
|
+
end
|
56
|
+
|
57
|
+
def resource_type_general
|
58
|
+
SO_TO_DC_TRANSLATIONS[type]
|
59
|
+
end
|
60
|
+
|
61
|
+
def doi
|
62
|
+
metadata.doi
|
63
|
+
end
|
64
|
+
|
65
|
+
def url
|
66
|
+
metadata.url
|
67
|
+
end
|
68
|
+
|
69
|
+
def id
|
70
|
+
normalize_doi(doi)
|
71
|
+
end
|
72
|
+
|
73
|
+
def author
|
74
|
+
Array(metadata.author).map do |a|
|
75
|
+
{ "@type" => "Person",
|
76
|
+
"givenName" => a.first,
|
77
|
+
"familyName" => a.last }.compact
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def title
|
82
|
+
metadata.title
|
83
|
+
end
|
84
|
+
|
85
|
+
def container_title
|
86
|
+
metadata.journal.to_s.presence || metadata.publisher.to_s
|
87
|
+
end
|
88
|
+
|
89
|
+
alias_method :journal, :container_title
|
90
|
+
|
91
|
+
def date_published
|
92
|
+
metadata.date.to_s.presence
|
93
|
+
end
|
94
|
+
|
95
|
+
def publication_year
|
96
|
+
metadata.year.to_s.presence
|
97
|
+
end
|
98
|
+
|
99
|
+
def is_part_of
|
100
|
+
if metadata.journal.present?
|
101
|
+
{ "type" => "Periodical",
|
102
|
+
"name" => metadata.journal.to_s,
|
103
|
+
"issn" => metadata.issn.to_s.presence }.compact
|
104
|
+
else
|
105
|
+
nil
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def description
|
110
|
+
{ "text" => metadata.field?(:abstract) && metadata.abstract.to_s.presence }
|
111
|
+
end
|
112
|
+
|
113
|
+
def license
|
114
|
+
{ "id" => metadata.field?(:copyright) && metadata.copyright.to_s.presence }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/bolognese/schema_org.rb
CHANGED
@@ -54,6 +54,14 @@ module Bolognese
|
|
54
54
|
metadata.fetch("@type", nil)
|
55
55
|
end
|
56
56
|
|
57
|
+
def citeproc_type
|
58
|
+
SO_TO_CP_TRANSLATIONS[type] || "article-journal"
|
59
|
+
end
|
60
|
+
|
61
|
+
def ris_type
|
62
|
+
SO_TO_RIS_TRANSLATIONS[resource_type_general.to_s.dasherize] || "GEN"
|
63
|
+
end
|
64
|
+
|
57
65
|
def additional_type
|
58
66
|
metadata.fetch("additionalType", nil)
|
59
67
|
end
|
data/lib/bolognese/utils.rb
CHANGED
@@ -41,30 +41,44 @@ module Bolognese
|
|
41
41
|
"datacite"
|
42
42
|
elsif options[:ext] == ".json" && Maremma.from_json(string).dig("resource", "xmlns").to_s.start_with?("http://datacite.org/schema/kernel")
|
43
43
|
"datacite_json"
|
44
|
+
elsif options[:ext] == ".json" && Maremma.from_json(string).dig("resource", "xmlns").to_s.start_with?("http://datacite.org/schema/kernel")
|
45
|
+
"citeproc"
|
46
|
+
elsif options[:ext] == ".ris"
|
47
|
+
"ris"
|
44
48
|
elsif options[:filename] == "codemeta.json"
|
45
49
|
"codemeta"
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
49
|
-
def
|
50
|
-
if from.
|
51
|
-
p = case from
|
52
|
-
when "crossref" then Crossref.new(id: id, string: string)
|
53
|
-
when "datacite" then Datacite.new(id: id, string: string, regenerate: options[:regenerate])
|
54
|
-
when "codemeta" then Codemeta.new(id: id, string: string)
|
55
|
-
when "datacite_json" then DataciteJson.new(string: string)
|
56
|
-
when "bibtex" then Bibtex.new(string: string)
|
57
|
-
else SchemaOrg.new(id: id)
|
58
|
-
end
|
59
|
-
|
60
|
-
if p.valid?
|
61
|
-
puts p.send(to)
|
62
|
-
else
|
63
|
-
$stderr.puts p.errors.colorize(:red)
|
64
|
-
end
|
65
|
-
else
|
53
|
+
def read(id: nil, string: nil, from: nil, **options)
|
54
|
+
if from.nil?
|
66
55
|
puts "not implemented"
|
56
|
+
return nil
|
67
57
|
end
|
58
|
+
|
59
|
+
p = case from
|
60
|
+
when "crossref" then Crossref.new(id: id, string: string)
|
61
|
+
when "datacite" then Datacite.new(id: id, string: string, regenerate: options[:regenerate])
|
62
|
+
when "codemeta" then Codemeta.new(id: id, string: string)
|
63
|
+
when "datacite_json" then DataciteJson.new(string: string)
|
64
|
+
when "citeproc" then Citeproc.new(id: id, string: string)
|
65
|
+
when "bibtex" then Bibtex.new(string: string)
|
66
|
+
when "ris" then Ris.new(string: string)
|
67
|
+
else SchemaOrg.new(id: id)
|
68
|
+
end
|
69
|
+
|
70
|
+
unless p.valid?
|
71
|
+
$stderr.puts p.errors.colorize(:red)
|
72
|
+
end
|
73
|
+
|
74
|
+
p
|
75
|
+
end
|
76
|
+
|
77
|
+
def write(id: nil, string: nil, from: nil, to: nil, **options)
|
78
|
+
metadata = read(id: id, string: string, from: from, **options)
|
79
|
+
return nil if metadata.nil?
|
80
|
+
|
81
|
+
puts metadata.send(to)
|
68
82
|
end
|
69
83
|
|
70
84
|
def orcid_from_url(url)
|
@@ -189,6 +203,40 @@ module Bolognese
|
|
189
203
|
end.unwrap
|
190
204
|
end
|
191
205
|
|
206
|
+
def from_citeproc(element)
|
207
|
+
Array.wrap(element).map do |a|
|
208
|
+
if a["literal"].present?
|
209
|
+
a["@type"] = "Organization"
|
210
|
+
a["name"] = a["literal"]
|
211
|
+
else
|
212
|
+
a["@type"] = "Person"
|
213
|
+
a["name"] = [a["given"], a["family"]].compact.join(" ")
|
214
|
+
end
|
215
|
+
a["givenName"] = a["given"]
|
216
|
+
a["familyName"] = a["family"]
|
217
|
+
a.except("given", "family", "literal").compact
|
218
|
+
end.unwrap
|
219
|
+
end
|
220
|
+
|
221
|
+
def to_citeproc(element)
|
222
|
+
Array.wrap(element).map do |a|
|
223
|
+
a["family"] = a["familyName"]
|
224
|
+
a["given"] = a["givenName"]
|
225
|
+
a["literal"] = a["name"] unless a["familyName"].present?
|
226
|
+
a.except("type", "@type", "id", "@id", "name", "familyName", "givenName").compact
|
227
|
+
end.unwrap
|
228
|
+
end
|
229
|
+
|
230
|
+
def to_ris(element)
|
231
|
+
Array.wrap(element).map do |a|
|
232
|
+
if a["familyName"].present?
|
233
|
+
[a["familyName"], a["givenName"]].join(", ")
|
234
|
+
else
|
235
|
+
a["name"]
|
236
|
+
end
|
237
|
+
end.unwrap
|
238
|
+
end
|
239
|
+
|
192
240
|
def sanitize(text, options={})
|
193
241
|
options[:tags] ||= Set.new(%w(strong em b i code pre sub sup br))
|
194
242
|
custom_scrubber = Bolognese::WhitelistScrubber.new(options)
|
@@ -236,5 +284,24 @@ module Bolognese
|
|
236
284
|
github_hash = github_from_url(url)
|
237
285
|
"https://raw.githubusercontent.com/#{github_hash[:owner]}/#{github_hash[:repo]}/master/codemeta.json" if github_hash[:owner].present?
|
238
286
|
end
|
287
|
+
|
288
|
+
def get_date_parts(iso8601_time)
|
289
|
+
return nil if iso8601_time.nil?
|
290
|
+
|
291
|
+
year = iso8601_time[0..3].to_i
|
292
|
+
month = iso8601_time[5..6].to_i
|
293
|
+
day = iso8601_time[8..9].to_i
|
294
|
+
{ 'date-parts' => [[year, month, day].reject { |part| part == 0 }] }
|
295
|
+
end
|
296
|
+
|
297
|
+
def get_date_from_date_parts(date_as_parts)
|
298
|
+
date_parts = date_as_parts.fetch("date-parts", []).first
|
299
|
+
year, month, day = date_parts[0], date_parts[1], date_parts[2]
|
300
|
+
get_date_from_parts(year, month, day)
|
301
|
+
end
|
302
|
+
|
303
|
+
def get_date_from_parts(year, month = nil, day = nil)
|
304
|
+
[year.to_s.rjust(4, '0'), month.to_s.rjust(2, '0'), day.to_s.rjust(2, '0')].reject { |part| part == "00" }.join("-")
|
305
|
+
end
|
239
306
|
end
|
240
307
|
end
|
data/lib/bolognese/version.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
2
|
<!-- Revision history
|
3
3
|
2010-08-26 Complete revision according to new common specification by the metadata work group after review. AJH, DTIC
|
4
|
-
2010-11-17 Revised to current state of kernel review, FZ, TIB
|
4
|
+
2010-11-17 Revised to current state of kernel review, FZ, TIB
|
5
5
|
2011-01-17 Complete revsion after community review. FZ, TIB
|
6
6
|
2011-03-17 Release of v2.1: added a namespace; mandatory properties got minLength; changes in the definitions of relationTypes
|
7
7
|
IsDocumentedBy/Documents and isCompiledBy/Compiles; changes type of property "Date" from xs:date to xs:string. FZ, TIB
|
8
8
|
2011-06-27 v2.2: namespace: kernel-2.2, additions to controlled lists "resourceType", "contributorType", "relatedIdentifierType", and "descriptionType". Removal of intermediate include-files.
|
9
|
-
2013-05 v3.0: namespace: kernel-3.0; delete LastMetadataUpdate & MetadateVersionNumber; additions to controlled lists "contributorType", "dateType", "descriptionType", "relationType", "relatedIdentifierType" & "resourceType"; deletion of "StartDate" & "EndDate" from list "dateType" and "Film" from "resourceType"; allow arbitrary order of elements; allow optional wrapper elements to be empty; include xml:lang attribute for title, subject & description; include attribute schemeURI for nameIdentifier of creator, contributor & subject; added new attributes "relatedMetadataScheme", "schemeURI" & "schemeType" to relatedIdentifier; included new property "geoLocation"
|
9
|
+
2013-05 v3.0: namespace: kernel-3.0; delete LastMetadataUpdate & MetadateVersionNumber; additions to controlled lists "contributorType", "dateType", "descriptionType", "relationType", "relatedIdentifierType" & "resourceType"; deletion of "StartDate" & "EndDate" from list "dateType" and "Film" from "resourceType"; allow arbitrary order of elements; allow optional wrapper elements to be empty; include xml:lang attribute for title, subject & description; include attribute schemeURI for nameIdentifier of creator, contributor & subject; added new attributes "relatedMetadataScheme", "schemeURI" & "schemeType" to relatedIdentifier; included new property "geoLocation"
|
10
10
|
2014-08-20 v3.1: additions to controlled lists "relationType", contributorType" and "relatedIdentifierType"; introduction of new child element "affiliation" to "creator" and "contributor"-->
|
11
11
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://datacite.org/schema/kernel-3" targetNamespace="http://datacite.org/schema/kernel-3" elementFormDefault="qualified" xml:lang="EN">
|
12
12
|
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
|
@@ -277,7 +277,7 @@
|
|
277
277
|
<xs:sequence>
|
278
278
|
<xs:element name="rights" minOccurs="0" maxOccurs="unbounded">
|
279
279
|
<xs:annotation>
|
280
|
-
<xs:documentation>Any rights information for this resource. Provide a rights management statement for the resource or reference a service providing such information. Include embargo information if applicable.
|
280
|
+
<xs:documentation>Any rights information for this resource. Provide a rights management statement for the resource or reference a service providing such information. Include embargo information if applicable.
|
281
281
|
Use the complete title of a license and include version information if applicable.</xs:documentation>
|
282
282
|
</xs:annotation>
|
283
283
|
<xs:complexType>
|
data/spec/bibtex_spec.rb
CHANGED
@@ -35,4 +35,38 @@ describe Bolognese::Bibtex, vcr: true do
|
|
35
35
|
expect(datacite.dig("creators", "creator").first).to eq("creatorName"=>"Sankar, Martial", "givenName"=>"Martial", "familyName"=>"Sankar")
|
36
36
|
end
|
37
37
|
end
|
38
|
+
|
39
|
+
context "get metadata as citeproc" do
|
40
|
+
it "Crossref DOI" do
|
41
|
+
json = JSON.parse(subject.citeproc)
|
42
|
+
expect(json["type"]).to eq("article-journal")
|
43
|
+
expect(json["id"]).to eq("https://doi.org/10.7554/elife.01567")
|
44
|
+
expect(json["DOI"]).to eq("10.7554/elife.01567")
|
45
|
+
expect(json["URL"]).to eq("http://elifesciences.org/lookup/doi/10.7554/eLife.01567")
|
46
|
+
expect(json["title"]).to eq("Automated quantitative histology reveals vascular morphodynamics during Arabidopsis hypocotyl secondary growth")
|
47
|
+
expect(json["author"]).to eq([{"family"=>"Sankar", "given"=>"Martial"},
|
48
|
+
{"family"=>"Nieminen", "given"=>"Kaisa"},
|
49
|
+
{"family"=>"Ragni", "given"=>"Laura"},
|
50
|
+
{"family"=>"Xenarios", "given"=>"Ioannis"},
|
51
|
+
{"family"=>"Hardtke", "given"=>"Christian S"}])
|
52
|
+
expect(json["container-title"]).to eq("eLife")
|
53
|
+
expect(json["issued"]).to eq("date-parts" => [[2014]])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "get metadata as ris" do
|
58
|
+
it "Crossref DOI" do
|
59
|
+
ris = subject.ris.split("\r\n")
|
60
|
+
expect(ris[0]).to eq("TY - JOUR")
|
61
|
+
expect(ris[1]).to eq("T1 - Automated quantitative histology reveals vascular morphodynamics during Arabidopsis hypocotyl secondary growth")
|
62
|
+
expect(ris[2]).to eq("T2 - eLife")
|
63
|
+
expect(ris[3]).to eq("AU - Sankar, Martial")
|
64
|
+
expect(ris[8]).to eq("DO - 10.7554/elife.01567")
|
65
|
+
expect(ris[9]).to eq("UR - http://elifesciences.org/lookup/doi/10.7554/eLife.01567")
|
66
|
+
expect(ris[10]).to eq("AB - Among various advantages, their small size makes model organisms preferred subjects of investigation. Yet, even in model systems detailed analysis of numerous developmental processes at cellular level is severely hampered by their scale.")
|
67
|
+
expect(ris[11]).to eq("PY - 2014")
|
68
|
+
expect(ris[12]).to eq("VL - 3")
|
69
|
+
expect(ris[13]).to eq("ER - ")
|
70
|
+
end
|
71
|
+
end
|
38
72
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bolognese::Citeproc, vcr: true do
|
4
|
+
let(:string) { IO.read(fixture_path + "citeproc.json") }
|
5
|
+
|
6
|
+
subject { Bolognese::Citeproc.new(string: string) }
|
7
|
+
|
8
|
+
context "get metadata" do
|
9
|
+
it "BlogPosting" do
|
10
|
+
expect(subject.valid?).to be true
|
11
|
+
expect(subject.id).to eq("https://doi.org/10.5438/4k3m-nyvg")
|
12
|
+
expect(subject.type).to eq("BlogPosting")
|
13
|
+
expect(subject.url).to eq("https://blog.datacite.org/eating-your-own-dog-food")
|
14
|
+
expect(subject.resource_type_general).to eq("Text")
|
15
|
+
expect(subject.author).to eq("type"=>"Person", "name"=>"Martin Fenner", "givenName"=>"Martin", "familyName"=>"Fenner")
|
16
|
+
expect(subject.title).to eq("Eating your own Dog Food")
|
17
|
+
expect(subject.description["text"]).to start_with("Eating your own dog food")
|
18
|
+
expect(subject.date_published).to eq("2016-12-20")
|
19
|
+
expect(subject.is_part_of).to eq("type"=>"Periodical", "name"=>"DataCite Blog")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "get metadata as datacite xml" do
|
24
|
+
it "BlogPosting" do
|
25
|
+
datacite = Maremma.from_xml(subject.datacite).fetch("resource", {})
|
26
|
+
expect(datacite.dig("resourceType", "resourceTypeGeneral")).to eq("Text")
|
27
|
+
expect(datacite.dig("titles", "title")).to eq("Eating your own Dog Food")
|
28
|
+
expect(datacite.dig("descriptions", "description", "__content__")).to start_with("Eating your own dog food")
|
29
|
+
expect(datacite.dig("creators", "creator")).to eq("creatorName"=>"Fenner, Martin", "givenName"=>"Martin", "familyName"=>"Fenner")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "get metadata as ris" do
|
34
|
+
it "BlogPosting" do
|
35
|
+
ris = subject.ris.split("\r\n")
|
36
|
+
expect(ris[0]).to eq("TY - GEN")
|
37
|
+
expect(ris[1]).to eq("T1 - Eating your own Dog Food")
|
38
|
+
expect(ris[2]).to eq("T2 - DataCite Blog")
|
39
|
+
expect(ris[3]).to eq("AU - Fenner, Martin")
|
40
|
+
expect(ris[4]).to eq("DO - 10.5438/4k3m-nyvg")
|
41
|
+
expect(ris[5]).to eq("UR - https://blog.datacite.org/eating-your-own-dog-food")
|
42
|
+
expect(ris[6]).to eq("AB - Eating your own dog food is a slang term to describe that an organization should itself use the products and services it provides. For DataCite this means that we should use DOIs with appropriate metadata and strategies for long-term preservation for...")
|
43
|
+
expect(ris[7]).to eq("PY - 2016")
|
44
|
+
expect(ris[8]).to eq("PB - DataCite")
|
45
|
+
expect(ris[9]).to eq("ER - ")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/spec/codemeta_spec.rb
CHANGED
@@ -98,14 +98,14 @@ describe Bolognese::Codemeta, vcr: true do
|
|
98
98
|
subject = Bolognese::Codemeta.new(string: string)
|
99
99
|
datacite = Maremma.from_xml(subject.datacite).fetch("resource", {})
|
100
100
|
expect(datacite.dig("titles", "title")).to eq("R Interface to the DataONE REST API")
|
101
|
-
expect(datacite.dig("creators", "creator")).to eq([{"creatorName"=>"Matt
|
101
|
+
expect(datacite.dig("creators", "creator")).to eq([{"creatorName"=>"Jones, Matt",
|
102
102
|
"givenName"=>"Matt",
|
103
103
|
"familyName"=>"Jones",
|
104
104
|
"nameIdentifier"=>
|
105
105
|
{"schemeURI"=>"http://orcid.org/",
|
106
106
|
"nameIdentifierScheme"=>"ORCID",
|
107
107
|
"__content__"=>"http://orcid.org/0000-0003-0077-4738"}},
|
108
|
-
{"creatorName"=>"Peter
|
108
|
+
{"creatorName"=>"Slaughter, Peter",
|
109
109
|
"givenName"=>"Peter",
|
110
110
|
"familyName"=>"Slaughter",
|
111
111
|
"nameIdentifier"=>
|
@@ -119,7 +119,7 @@ describe Bolognese::Codemeta, vcr: true do
|
|
119
119
|
it "maremma" do
|
120
120
|
datacite = Maremma.from_xml(subject.datacite).fetch("resource", {})
|
121
121
|
expect(datacite.dig("titles", "title")).to eq("Maremma: a Ruby library for simplified network calls")
|
122
|
-
expect(datacite.dig("creators", "creator")).to eq("creatorName"=>"Martin
|
122
|
+
expect(datacite.dig("creators", "creator")).to eq("creatorName"=>"Fenner, Martin", "givenName"=>"Martin", "familyName"=>"Fenner", "nameIdentifier"=>{"schemeURI"=>"http://orcid.org/", "nameIdentifierScheme"=>"ORCID", "__content__"=>"http://orcid.org/0000-0003-0077-4738"})
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
@@ -168,4 +168,34 @@ describe Bolognese::Codemeta, vcr: true do
|
|
168
168
|
expect(bibtex[:year]).to eq("2017")
|
169
169
|
end
|
170
170
|
end
|
171
|
+
|
172
|
+
context "get metadata as citeproc" do
|
173
|
+
it "maremma" do
|
174
|
+
json = JSON.parse(subject.citeproc)
|
175
|
+
expect(json["type"]).to eq("computer_program")
|
176
|
+
expect(json["id"]).to eq("https://doi.org/10.5438/qeg0-3gm3")
|
177
|
+
expect(json["DOI"]).to eq("10.5438/qeg0-3gm3")
|
178
|
+
expect(json["title"]).to eq("Maremma: a Ruby library for simplified network calls")
|
179
|
+
expect(json["author"]).to eq("family" => "Fenner", "given" => "Martin")
|
180
|
+
expect(json["publisher"]).to eq("DataCite")
|
181
|
+
expect(json["issued"]).to eq("date-parts" => [[2017, 2, 24]])
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context "get metadata as ris" do
|
186
|
+
it "maremma" do
|
187
|
+
ris = subject.ris.split("\r\n")
|
188
|
+
expect(ris[0]).to eq("TY - COMP")
|
189
|
+
expect(ris[1]).to eq("T1 - Maremma: a Ruby library for simplified network calls")
|
190
|
+
expect(ris[2]).to eq("T2 - DataCite")
|
191
|
+
expect(ris[3]).to eq("AU - Fenner, Martin")
|
192
|
+
expect(ris[4]).to eq("DO - 10.5438/qeg0-3gm3")
|
193
|
+
expect(ris[5]).to eq("UR - https://github.com/datacite/maremma")
|
194
|
+
expect(ris[6]).to eq("AB - Ruby utility library for network requests. Based on Faraday and Excon, provides a wrapper for XML/JSON parsing and error handling. All successful responses are returned as hash with key data, all errors in a JSONAPI-friendly hash with key errors.")
|
195
|
+
expect(ris[7]).to eq("KW - faraday")
|
196
|
+
expect(ris[10]).to eq("PY - 2017")
|
197
|
+
expect(ris[11]).to eq("PB - DataCite")
|
198
|
+
expect(ris[12]).to eq("ER - ")
|
199
|
+
end
|
200
|
+
end
|
171
201
|
end
|
data/spec/crossref_spec.rb
CHANGED
@@ -181,7 +181,7 @@ describe Bolognese::Crossref, vcr: true do
|
|
181
181
|
datacite = Maremma.from_xml(subject.datacite).fetch("resource", {})
|
182
182
|
expect(datacite.dig("resourceType", "resourceTypeGeneral")).to eq("Text")
|
183
183
|
expect(datacite.dig("creators", "creator").count).to eq(7)
|
184
|
-
expect(datacite.dig("creators", "creator")[2]).to eq("creatorName" => "Beatriz
|
184
|
+
expect(datacite.dig("creators", "creator")[2]).to eq("creatorName" => "Hernandez, Beatriz",
|
185
185
|
+"familyName" => "Hernandez",
|
186
186
|
+"givenName" => "Beatriz",
|
187
187
|
"nameIdentifier" => {"schemeURI"=>"http://orcid.org/", "nameIdentifierScheme"=>"ORCID", "__content__"=>"http://orcid.org/0000-0003-2043-4925"})
|
@@ -191,7 +191,7 @@ describe Bolognese::Crossref, vcr: true do
|
|
191
191
|
id = "https://doi.org/10.1371/journal.pone.0000030"
|
192
192
|
subject = Bolognese::Crossref.new(id: id)
|
193
193
|
datacite = Maremma.from_xml(subject.datacite).fetch("resource", {})
|
194
|
-
expect(datacite.dig("contributors", "contributor")).to eq("contributorType"=>"Editor", "contributorName"=>"Guilhem
|
194
|
+
expect(datacite.dig("contributors", "contributor")).to eq("contributorType"=>"Editor", "contributorName"=>"Janbon, Guilhem", "givenName"=>"Guilhem", "familyName"=>"Janbon")
|
195
195
|
end
|
196
196
|
end
|
197
197
|
|
@@ -223,4 +223,82 @@ describe Bolognese::Crossref, vcr: true do
|
|
223
223
|
expect(bibtex[:year]).to eq("2012")
|
224
224
|
end
|
225
225
|
end
|
226
|
+
|
227
|
+
context "get metadata as citeproc" do
|
228
|
+
it "journal article" do
|
229
|
+
id = "10.7554/eLife.01567"
|
230
|
+
subject = Bolognese::Crossref.new(id: id)
|
231
|
+
expect(subject.valid?).to be true
|
232
|
+
json = JSON.parse(subject.citeproc)
|
233
|
+
expect(json["type"]).to eq("article-journal")
|
234
|
+
expect(json["id"]).to eq("https://doi.org/10.7554/elife.01567")
|
235
|
+
expect(json["DOI"]).to eq("10.7554/eLife.01567")
|
236
|
+
expect(json["title"]).to eq("Automated quantitative histology reveals vascular morphodynamics during Arabidopsis hypocotyl secondary growth")
|
237
|
+
expect(json["author"]).to eq([{"family"=>"Sankar", "given"=>"Martial"},
|
238
|
+
{"family"=>"Nieminen", "given"=>"Kaisa"},
|
239
|
+
{"family"=>"Ragni", "given"=>"Laura"},
|
240
|
+
{"family"=>"Xenarios", "given"=>"Ioannis"},
|
241
|
+
{"family"=>"Hardtke", "given"=>"Christian S"}])
|
242
|
+
expect(json["container-title"]).to eq("eLife")
|
243
|
+
expect(json["volume"]).to eq("3")
|
244
|
+
expect(json["issued"]).to eq("date-parts" => [[2014, 2, 11]])
|
245
|
+
end
|
246
|
+
|
247
|
+
it "with pages" do
|
248
|
+
id = "https://doi.org/10.1155/2012/291294"
|
249
|
+
subject = Bolognese::Crossref.new(id: id)
|
250
|
+
expect(subject.valid?).to be true
|
251
|
+
json = JSON.parse(subject.citeproc)
|
252
|
+
expect(json["type"]).to eq("article-journal")
|
253
|
+
expect(json["id"]).to eq("https://doi.org/10.1155/2012/291294")
|
254
|
+
expect(json["DOI"]).to eq("10.1155/2012/291294")
|
255
|
+
expect(json["title"]).to eq("Delineating a Retesting Zone Using Receiver Operating Characteristic Analysis on Serial QuantiFERON Tuberculosis Test Results in US Healthcare Workers")
|
256
|
+
expect(json["author"]).to eq([{"family"=>"Thanassi", "given"=>"Wendy"},
|
257
|
+
{"family"=>"Noda", "given"=>"Art"},
|
258
|
+
{"family"=>"Hernandez", "given"=>"Beatriz"},
|
259
|
+
{"family"=>"Newell", "given"=>"Jeffery"},
|
260
|
+
{"family"=>"Terpeluk", "given"=>"Paul"},
|
261
|
+
{"family"=>"Marder", "given"=>"David"},
|
262
|
+
{"family"=>"Yesavage", "given"=>"Jerome A."}])
|
263
|
+
expect(json["container-title"]).to eq("Pulmonary Medicine")
|
264
|
+
expect(json["volume"]).to eq("2012")
|
265
|
+
expect(json["page"]).to eq("1-7")
|
266
|
+
expect(json["issued"]).to eq("date-parts"=>[[2012]])
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
context "get metadata as ris" do
|
271
|
+
it "journal article" do
|
272
|
+
id = "10.7554/eLife.01567"
|
273
|
+
subject = Bolognese::Crossref.new(id: id)
|
274
|
+
expect(subject.valid?).to be true
|
275
|
+
ris = subject.ris.split("\r\n")
|
276
|
+
expect(ris[0]).to eq("TY - JOUR")
|
277
|
+
expect(ris[1]).to eq("T1 - Automated quantitative histology reveals vascular morphodynamics during Arabidopsis hypocotyl secondary growth")
|
278
|
+
expect(ris[2]).to eq("T2 - eLife")
|
279
|
+
expect(ris[3]).to eq("AU - Sankar, Martial")
|
280
|
+
expect(ris[8]).to eq("DO - 10.7554/eLife.01567")
|
281
|
+
expect(ris[9]).to eq("UR - http://elifesciences.org/lookup/doi/10.7554/eLife.01567")
|
282
|
+
expect(ris[10]).to eq("PY - 2014")
|
283
|
+
expect(ris[11]).to eq("VL - 3")
|
284
|
+
expect(ris[12]).to eq("ER - ")
|
285
|
+
end
|
286
|
+
|
287
|
+
it "with pages" do
|
288
|
+
id = "https://doi.org/10.1155/2012/291294"
|
289
|
+
subject = Bolognese::Crossref.new(id: id)
|
290
|
+
expect(subject.valid?).to be true
|
291
|
+
ris = subject.ris.split("\r\n")
|
292
|
+
expect(ris[0]).to eq("TY - JOUR")
|
293
|
+
expect(ris[1]).to eq("T1 - Delineating a Retesting Zone Using Receiver Operating Characteristic Analysis on Serial QuantiFERON Tuberculosis Test Results in US Healthcare Workers")
|
294
|
+
expect(ris[2]).to eq("T2 - Pulmonary Medicine")
|
295
|
+
expect(ris[3]).to eq("AU - Thanassi, Wendy")
|
296
|
+
expect(ris[10]).to eq("DO - 10.1155/2012/291294")
|
297
|
+
expect(ris[11]).to eq("UR - http://www.hindawi.com/journals/pm/2012/291294/")
|
298
|
+
expect(ris[12]).to eq("PY - 2012")
|
299
|
+
expect(ris[13]).to eq("VL - 2012")
|
300
|
+
expect(ris[14]).to eq("SP - 1-7")
|
301
|
+
expect(ris[15]).to eq("ER - ")
|
302
|
+
end
|
303
|
+
end
|
226
304
|
end
|