commonmeta-ruby 3.4.5 → 3.5.1
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/Gemfile.lock +8 -8
- data/csl-data.json +538 -0
- data/lib/commonmeta/author_utils.rb +103 -71
- data/lib/commonmeta/crossref_utils.rb +31 -25
- data/lib/commonmeta/metadata.rb +8 -14
- data/lib/commonmeta/metadata_utils.rb +4 -3
- data/lib/commonmeta/readers/bibtex_reader.rb +3 -3
- data/lib/commonmeta/readers/cff_reader.rb +7 -6
- data/lib/commonmeta/readers/codemeta_reader.rb +3 -3
- data/lib/commonmeta/readers/crossref_reader.rb +131 -124
- data/lib/commonmeta/readers/crossref_xml_reader.rb +7 -6
- data/lib/commonmeta/readers/csl_reader.rb +3 -4
- data/lib/commonmeta/readers/datacite_reader.rb +5 -5
- data/lib/commonmeta/readers/json_feed_reader.rb +8 -4
- data/lib/commonmeta/readers/npm_reader.rb +2 -2
- data/lib/commonmeta/readers/ris_reader.rb +1 -1
- data/lib/commonmeta/readers/schema_org_reader.rb +6 -4
- data/lib/commonmeta/schema_utils.rb +1 -1
- data/lib/commonmeta/utils.rb +4 -2
- data/lib/commonmeta/version.rb +1 -1
- data/lib/commonmeta/writers/bibtex_writer.rb +1 -1
- data/lib/commonmeta/writers/cff_writer.rb +5 -4
- data/lib/commonmeta/writers/codemeta_writer.rb +4 -2
- data/lib/commonmeta/writers/csv_writer.rb +4 -2
- data/lib/commonmeta/writers/datacite_writer.rb +1 -1
- data/lib/commonmeta/writers/jats_writer.rb +9 -5
- data/lib/commonmeta/writers/ris_writer.rb +2 -1
- data/lib/commonmeta/writers/schema_org_writer.rb +7 -4
- data/resources/{commonmeta_v0.9.3.json → commonmeta_v0.10.3.json} +138 -55
- data/resources/csl-citation.json +99 -0
- data/spec/author_utils_spec.rb +16 -16
- data/spec/cli_spec.rb +1 -1
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_crossref_metadata/missing_contributor.yml +307 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_datacite_metadata/SoftwareSourceCode.yml +76 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/archived_wordpress_post.yml +119 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/book_oup.yml +107 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/journal_article_plos.yml +407 -0
- data/spec/metadata_spec.rb +2 -2
- data/spec/readers/bibtex_reader_spec.rb +5 -5
- data/spec/readers/cff_reader_spec.rb +127 -127
- data/spec/readers/codemeta_reader_spec.rb +11 -11
- data/spec/readers/crossref_reader_spec.rb +844 -835
- data/spec/readers/crossref_xml_reader_spec.rb +899 -901
- data/spec/readers/csl_reader_spec.rb +33 -33
- data/spec/readers/datacite_reader_spec.rb +106 -103
- data/spec/readers/json_feed_reader_spec.rb +68 -40
- data/spec/readers/npm_reader_spec.rb +32 -33
- data/spec/readers/ris_reader_spec.rb +36 -36
- data/spec/readers/schema_org_reader_spec.rb +289 -288
- data/spec/writers/codemeta_writer_spec.rb +19 -20
- data/spec/writers/crossref_xml_writer_spec.rb +73 -37
- data/spec/writers/datacite_writer_spec.rb +2 -1
- metadata +10 -3
@@ -4,19 +4,19 @@ module Commonmeta
|
|
4
4
|
module Readers
|
5
5
|
module CrossrefReader
|
6
6
|
def get_crossref(id: nil, **options)
|
7
|
-
return {
|
7
|
+
return { "string" => nil, "state" => "not_found" } unless id.present?
|
8
8
|
|
9
9
|
api_url = crossref_api_url(id, options)
|
10
10
|
response = HTTP.get(api_url)
|
11
|
-
return {
|
11
|
+
return { "string" => nil, "state" => "not_found" } unless response.status.success?
|
12
12
|
|
13
|
-
{
|
13
|
+
{ "string" => response.body.to_s }
|
14
14
|
end
|
15
15
|
|
16
16
|
def read_crossref(string: nil, **options)
|
17
17
|
if string.present?
|
18
18
|
errors = jsonlint(string)
|
19
|
-
return {
|
19
|
+
return { "errors" => errors } if errors.present?
|
20
20
|
end
|
21
21
|
|
22
22
|
read_options = ActiveSupport::HashWithIndifferentAccess.new(options.except(:doi, :id, :url,
|
@@ -24,161 +24,168 @@ module Commonmeta
|
|
24
24
|
meta = string.present? ? JSON.parse(string) : {}
|
25
25
|
|
26
26
|
# optionally strip out the message wrapper from API
|
27
|
-
meta = meta.dig(
|
27
|
+
meta = meta.dig("message") if meta.dig("message").present?
|
28
28
|
|
29
|
-
resource_type = meta.fetch(
|
29
|
+
resource_type = meta.fetch("type", nil)
|
30
30
|
resource_type = resource_type.present? ? resource_type.underscore.camelcase : nil
|
31
|
-
type = Commonmeta::Utils::CR_TO_CM_TRANSLATIONS.fetch(resource_type,
|
31
|
+
type = Commonmeta::Utils::CR_TO_CM_TRANSLATIONS.fetch(resource_type, "Other")
|
32
32
|
|
33
|
-
member_id = meta.fetch(
|
33
|
+
member_id = meta.fetch("member", nil)
|
34
34
|
# TODO: get publisher from member_id almost always return publisher name, but sometimes does not
|
35
35
|
publisher = if member_id.present?
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
editors = Array.wrap(meta.fetch(
|
47
|
-
contributors
|
36
|
+
get_crossref_member(member_id)
|
37
|
+
else
|
38
|
+
meta.fetch("publisher", nil)
|
39
|
+
end
|
40
|
+
|
41
|
+
contributors = if meta.fetch("author", nil).present?
|
42
|
+
get_authors(from_csl(Array.wrap(meta.fetch("author", nil))))
|
43
|
+
else
|
44
|
+
[]
|
45
|
+
end
|
46
|
+
editors = Array.wrap(meta.fetch("editor", nil)).each { |e| e["contributorType"] = "Editor" }
|
47
|
+
contributors += get_authors(from_csl(editors))
|
48
48
|
|
49
49
|
date = {}
|
50
|
-
date[
|
51
|
-
date[
|
52
|
-
date[
|
53
|
-
meta.dig(
|
54
|
-
|
50
|
+
date["submitted"] = nil
|
51
|
+
date["accepted"] = meta.dig("accepted", "date-time")
|
52
|
+
date["published"] =
|
53
|
+
meta.dig("issued",
|
54
|
+
"date-time") || get_date_from_date_parts(meta.fetch("issued",
|
55
55
|
nil)) || get_date_from_date_parts(meta.fetch(
|
56
|
-
|
57
|
-
|
58
|
-
date[
|
59
|
-
meta.dig(
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
56
|
+
"created", nil
|
57
|
+
))
|
58
|
+
date["updated"] =
|
59
|
+
meta.dig("updated",
|
60
|
+
"date-time") || meta.dig("deposited",
|
61
|
+
"date-time") || get_date_from_date_parts(meta.fetch(
|
62
|
+
"deposited", nil
|
63
|
+
))
|
64
64
|
|
65
65
|
# TODO: fix timestamp. Until then, remove time as this is not always stable with Crossref (different server timezones)
|
66
|
-
date[
|
67
|
-
date[
|
66
|
+
date["published"] = get_iso8601_date(date["published"]) if date["published"].present?
|
67
|
+
date["updated"] = get_iso8601_date(date["updated"]) if date["updated"].present?
|
68
68
|
|
69
|
-
license = if meta.fetch(
|
70
|
-
|
71
|
-
|
72
|
-
issn = Array.wrap(meta.fetch(
|
73
|
-
Array.wrap(meta.fetch(
|
74
|
-
issn = issn.fetch(
|
69
|
+
license = if meta.fetch("license", nil)
|
70
|
+
hsh_to_spdx("rightsURI" => meta.dig("license", 0, "URL"))
|
71
|
+
end
|
72
|
+
issn = Array.wrap(meta.fetch("issn-type", nil)).find { |i| i["type"] == "electronic" } ||
|
73
|
+
Array.wrap(meta.fetch("issn-type", nil)).find { |i| i["type"] == "print" } || {}
|
74
|
+
issn = issn.fetch("value", nil) if issn.present?
|
75
75
|
|
76
|
-
references = Array.wrap(meta.fetch(
|
76
|
+
references = Array.wrap(meta.fetch("reference", nil)).map { |r| get_reference(r) }
|
77
77
|
|
78
|
-
funding_references = Array.wrap(meta.fetch(
|
78
|
+
funding_references = Array.wrap(meta.fetch("funder", nil)).reduce([]) do |sum, funding|
|
79
79
|
funding_reference = {
|
80
|
-
|
81
|
-
|
82
|
-
|
80
|
+
"funderName" => funding["name"],
|
81
|
+
"funderIdentifier" => funding["DOI"] ? doi_as_url(funding["DOI"]) : nil,
|
82
|
+
"funderIdentifierType" => funding["DOI"].to_s.starts_with?("10.13039") ? "Crossref Funder ID" : nil,
|
83
83
|
}.compact
|
84
|
-
if funding[
|
85
|
-
Array.wrap(funding[
|
86
|
-
funding_reference[
|
84
|
+
if funding["name"].present? && funding["award"].present?
|
85
|
+
Array.wrap(funding["award"]).each do |award|
|
86
|
+
funding_reference["awardNumber"] = award
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
90
|
sum += [funding_reference] if funding_reference.present?
|
91
91
|
sum
|
92
92
|
end
|
93
|
+
files = Array.wrap(meta.fetch("link", nil)).reduce([]) do |sum, file|
|
94
|
+
if file["content-type"] != "unspecified"
|
95
|
+
file = { "url" => file.fetch("URL", nil), "mimeType" => file.fetch("content-type", nil) }
|
96
|
+
sum += [file]
|
97
|
+
end
|
98
|
+
sum
|
99
|
+
end
|
100
|
+
|
93
101
|
container_type = case resource_type
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
first_page = if meta.fetch(
|
103
|
-
|
104
|
-
|
105
|
-
last_page = if meta.fetch(
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
container = {
|
110
|
-
|
102
|
+
when "JournalArticle", "JournalIssue"
|
103
|
+
"Journal"
|
104
|
+
when "BookChapter"
|
105
|
+
"Book"
|
106
|
+
when "Monograph"
|
107
|
+
"BookSeries"
|
108
|
+
end
|
109
|
+
|
110
|
+
first_page = if meta.fetch("page", nil).present?
|
111
|
+
meta.fetch("page").split("-").map(&:strip)[0]
|
112
|
+
end
|
113
|
+
last_page = if meta.fetch("page", nil).present?
|
114
|
+
meta.fetch("page").split("-").map(&:strip)[1]
|
115
|
+
end
|
116
|
+
|
117
|
+
container = { "type" => container_type,
|
118
|
+
"title" => parse_attributes(meta.fetch("container-title", nil),
|
111
119
|
first: true).to_s.squish.presence,
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
id = normalize_id(meta.fetch(
|
120
|
-
|
121
|
-
id = normalize_doi(options[:doi] || options[:id] || meta.fetch(
|
122
|
-
title = if meta.fetch(
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
title = title.blank? ?
|
128
|
-
state = meta.present? || read_options.present? ?
|
129
|
-
subjects = Array.wrap(meta.fetch(
|
120
|
+
"identifier" => issn.present? ? issn : nil,
|
121
|
+
"identifierType" => issn.present? ? "ISSN" : nil,
|
122
|
+
"volume" => meta.fetch("volume", nil),
|
123
|
+
"issue" => meta.fetch("issue", nil),
|
124
|
+
"firstPage" => first_page,
|
125
|
+
"lastPage" => last_page }.compact
|
126
|
+
|
127
|
+
id = normalize_id(meta.fetch("id", nil) || meta.fetch("DOI", nil))
|
128
|
+
|
129
|
+
id = normalize_doi(options[:doi] || options[:id] || meta.fetch("DOI", nil))
|
130
|
+
title = if meta.fetch("title", nil).is_a?(Array)
|
131
|
+
meta.fetch("title", nil)[0]
|
132
|
+
else
|
133
|
+
meta.fetch("title", nil)
|
134
|
+
end
|
135
|
+
title = title.blank? ? ":(unav)" : title.squish
|
136
|
+
state = meta.present? || read_options.present? ? "findable" : "not_found"
|
137
|
+
subjects = Array.wrap(meta.fetch("categories", nil)).reduce([]) do |sum, subject|
|
130
138
|
sum += name_to_fos(subject)
|
131
139
|
|
132
140
|
sum
|
133
141
|
end
|
134
|
-
abstract = meta.fetch(
|
142
|
+
abstract = meta.fetch("abstract", nil)
|
135
143
|
provider = get_doi_ra(id)
|
136
144
|
|
137
|
-
{
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
145
|
+
{ "id" => id,
|
146
|
+
"type" => type,
|
147
|
+
"url" => normalize_id(meta.dig("resource", "primary", "URL")),
|
148
|
+
"titles" => [{ "title" => title }],
|
149
|
+
"contributors" => contributors,
|
150
|
+
"container" => container,
|
151
|
+
"publisher" => publisher,
|
152
|
+
"references" => references,
|
153
|
+
"date" => date.compact,
|
154
|
+
"descriptions" => if abstract.present?
|
155
|
+
[{ "description" => sanitize(abstract),
|
156
|
+
"descriptionType" => "Abstract" }]
|
157
|
+
else
|
158
|
+
[]
|
159
|
+
end,
|
160
|
+
"license" => license,
|
161
|
+
"alternate_identifiers" => [],
|
162
|
+
"funding_references" => funding_references,
|
163
|
+
"files" => files.presence,
|
164
|
+
"version" => meta.fetch("version", nil),
|
165
|
+
"subjects" => subjects,
|
166
|
+
"provider" => provider,
|
167
|
+
"schema_version" => "http://datacite.org/schema/kernel-4",
|
168
|
+
"state" => state }.compact.merge(read_options)
|
161
169
|
end
|
162
170
|
|
163
171
|
def get_reference(reference)
|
164
172
|
return nil unless reference.present? || !reference.is_a?(Hash)
|
165
173
|
|
166
|
-
doi = reference.dig(
|
174
|
+
doi = reference.dig("DOI")
|
167
175
|
{
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
'unstructured' => doi.nil? ? reference.dig('unstructured') : nil
|
176
|
+
"key" => reference.dig("key"),
|
177
|
+
"doi" => doi ? normalize_doi(doi) : nil,
|
178
|
+
"contributor" => reference.dig("author"),
|
179
|
+
"title" => reference.dig("article-title"),
|
180
|
+
"publisher" => reference.dig("publisher"),
|
181
|
+
"publicationYear" => reference.dig("year"),
|
182
|
+
"volume" => reference.dig("volume"),
|
183
|
+
"issue" => reference.dig("issue"),
|
184
|
+
"firstPage" => reference.dig("first-page"),
|
185
|
+
"lastPage" => reference.dig("last-page"),
|
186
|
+
"containerTitle" => reference.dig("journal-title"),
|
187
|
+
"edition" => nil,
|
188
|
+
"unstructured" => doi.nil? ? reference.dig("unstructured") : nil,
|
182
189
|
}.compact
|
183
190
|
end
|
184
191
|
end
|
@@ -101,6 +101,9 @@ module Commonmeta
|
|
101
101
|
resource_type = resource_type.present? ? resource_type.underscore.camelcase : nil
|
102
102
|
type = Commonmeta::Utils::CR_TO_CM_TRANSLATIONS.fetch(resource_type, 'Other')
|
103
103
|
|
104
|
+
contributors = crossref_people(bibmeta, 'author')
|
105
|
+
contributors += crossref_people(bibmeta, 'editor')
|
106
|
+
|
104
107
|
titles = if bibmeta['titles'].present?
|
105
108
|
Array.wrap(bibmeta['titles']).map do |r|
|
106
109
|
if r.blank? || (r['title'].blank? && r['original_language_title'].blank?)
|
@@ -192,8 +195,7 @@ module Commonmeta
|
|
192
195
|
'url' => url,
|
193
196
|
'titles' => titles,
|
194
197
|
'alternate_identifiers' => alternate_identifiers,
|
195
|
-
'
|
196
|
-
'contributors' => crossref_people(bibmeta, 'editor'),
|
198
|
+
'contributors' => contributors,
|
197
199
|
'funding_references' => crossref_funding_reference(program_metadata),
|
198
200
|
'publisher' => { 'name' => publisher },
|
199
201
|
'container' => container,
|
@@ -296,11 +298,11 @@ module Commonmeta
|
|
296
298
|
'givenName' => given_name,
|
297
299
|
'familyName' => family_name,
|
298
300
|
'affiliation' => affiliation.presence,
|
299
|
-
'
|
301
|
+
'contributorRoles' => contributor_role == 'editor' ? ['Editor'] : ['Author'] }.compact
|
300
302
|
else
|
301
303
|
{ 'type' => 'Organization',
|
302
304
|
'name' => a['name'] || a['__content__'],
|
303
|
-
'
|
305
|
+
'contributorRoles' => contributor_role == 'editor' ? ['Editor'] : ['Author'] }.compact
|
304
306
|
end
|
305
307
|
end
|
306
308
|
end
|
@@ -359,7 +361,7 @@ module Commonmeta
|
|
359
361
|
{
|
360
362
|
'key' => reference.dig('key'),
|
361
363
|
'doi' => doi ? normalize_doi(doi) : nil,
|
362
|
-
'
|
364
|
+
'contributor' => reference.dig('author'),
|
363
365
|
'title' => reference.dig('article_title'),
|
364
366
|
'publisher' => reference.dig('publisher'),
|
365
367
|
'publicationYear' => reference.dig('cYear'),
|
@@ -369,7 +371,6 @@ module Commonmeta
|
|
369
371
|
'lastPage' => reference.dig('last_page'),
|
370
372
|
'containerTitle' => reference.dig('journal_title'),
|
371
373
|
'edition' => nil,
|
372
|
-
'contributor' => nil,
|
373
374
|
'unstructured' => doi.nil? ? reference.dig('unstructured') : nil
|
374
375
|
}.compact
|
375
376
|
end.unwrap
|
@@ -17,12 +17,12 @@ module Commonmeta
|
|
17
17
|
citeproc_type = meta.fetch('type', nil)
|
18
18
|
type = Commonmeta::Utils::CSL_TO_CM_TRANSLATIONS.fetch(citeproc_type, 'Other')
|
19
19
|
|
20
|
-
|
20
|
+
contributors = if meta.fetch('author', nil).present?
|
21
21
|
get_authors(from_csl(Array.wrap(meta.fetch('author', nil))))
|
22
22
|
else
|
23
|
-
[{ 'type' => 'Organization', 'name' => ':(unav)' }]
|
23
|
+
[{ 'type' => 'Organization', 'name' => ':(unav)', 'contributorRoles' => ['Author'] }]
|
24
24
|
end
|
25
|
-
contributors
|
25
|
+
contributors += get_authors(from_csl(Array.wrap(meta.fetch('editor', nil))))
|
26
26
|
|
27
27
|
date = {}
|
28
28
|
d = get_date_from_date_parts(meta.fetch('issued', nil))
|
@@ -62,7 +62,6 @@ module Commonmeta
|
|
62
62
|
'type' => type,
|
63
63
|
'url' => normalize_id(meta.fetch('URL', nil)),
|
64
64
|
'titles' => [{ 'title' => meta.fetch('title', nil) }],
|
65
|
-
'creators' => creators,
|
66
65
|
'contributors' => contributors,
|
67
66
|
'container' => container,
|
68
67
|
'publisher' => if meta.fetch('publisher', nil)
|
@@ -53,10 +53,10 @@ module Commonmeta
|
|
53
53
|
titles = Array.wrap(meta.fetch('titles', nil)).map do |title|
|
54
54
|
title.compact
|
55
55
|
end
|
56
|
-
|
56
|
+
contributors = get_authors(from_datacite(meta.fetch('creators', nil)))
|
57
|
+
contributors += get_authors(from_datacite(meta.fetch('contributors', nil)))
|
57
58
|
publisher = { 'name' => meta.fetch('publisher', nil) }
|
58
59
|
|
59
|
-
contributors = get_authors(from_datacite(meta.fetch('contributors', nil)))
|
60
60
|
container = meta.fetch('container', nil)
|
61
61
|
funding_references = meta.fetch('funding_references', nil)
|
62
62
|
|
@@ -88,6 +88,7 @@ module Commonmeta
|
|
88
88
|
end.map do |reference|
|
89
89
|
get_datacite_reference(reference)
|
90
90
|
end
|
91
|
+
files = Array.wrap(meta.fetch("content_url", nil)).map { |file| { "url" => file } }
|
91
92
|
formats = meta.fetch('formats', nil)
|
92
93
|
sizes = meta.fetch('sizes', nil)
|
93
94
|
schema_version = meta.fetch('schema_version', nil) || 'http://datacite.org/schema/kernel-4'
|
@@ -98,7 +99,6 @@ module Commonmeta
|
|
98
99
|
'additional_type' => resource_type == type ? nil : resource_type,
|
99
100
|
'url' => url,
|
100
101
|
'titles' => titles,
|
101
|
-
'creators' => creators,
|
102
102
|
'contributors' => contributors,
|
103
103
|
'container' => container,
|
104
104
|
'publisher' => publisher,
|
@@ -106,6 +106,7 @@ module Commonmeta
|
|
106
106
|
'alternate_identifiers' => alternate_identifiers.presence,
|
107
107
|
'references' => references,
|
108
108
|
'funding_references' => funding_references,
|
109
|
+
'files' => files.presence,
|
109
110
|
'date' => date.compact,
|
110
111
|
'descriptions' => descriptions,
|
111
112
|
'license' => license,
|
@@ -150,7 +151,7 @@ module Commonmeta
|
|
150
151
|
'key' => key,
|
151
152
|
'doi' => doi,
|
152
153
|
'url' => url,
|
153
|
-
'
|
154
|
+
'contributor' => reference.dig('author'),
|
154
155
|
'title' => reference.dig('article-title'),
|
155
156
|
'publisher' => reference.dig('publisher'),
|
156
157
|
'publicationYear' => reference.dig('year'),
|
@@ -160,7 +161,6 @@ module Commonmeta
|
|
160
161
|
'lastPage' => reference.dig('last-page'),
|
161
162
|
'containerTitle' => reference.dig('journal-title'),
|
162
163
|
'edition' => nil,
|
163
|
-
'contributor' => nil,
|
164
164
|
'unstructured' => doi.nil? ? reference.dig('unstructured') : nil
|
165
165
|
}.compact
|
166
166
|
end
|
@@ -20,12 +20,16 @@ module Commonmeta
|
|
20
20
|
|
21
21
|
meta = string.present? ? JSON.parse(string) : {}
|
22
22
|
|
23
|
-
|
23
|
+
if (meta.dig("blog", "status") == "archived")
|
24
|
+
url = normalize_url(meta.fetch("archive_url", nil))
|
25
|
+
else
|
26
|
+
url = normalize_url(meta.fetch("url", nil))
|
27
|
+
end
|
24
28
|
id = options[:doi] ? normalize_doi(options[:doi]) : normalize_id(meta.fetch("doi", nil))
|
25
|
-
id = url if id.blank?
|
29
|
+
id = normalize_url(meta.fetch("url", nil)) if id.blank?
|
26
30
|
|
27
31
|
type = "Article"
|
28
|
-
|
32
|
+
contributors = if meta.fetch("authors", nil).present?
|
29
33
|
get_authors(from_json_feed(Array.wrap(meta.fetch("authors"))))
|
30
34
|
else
|
31
35
|
[{ "type" => "Organization", "name" => ":(unav)" }]
|
@@ -70,7 +74,7 @@ module Commonmeta
|
|
70
74
|
"type" => type,
|
71
75
|
"url" => url,
|
72
76
|
"titles" => titles,
|
73
|
-
"
|
77
|
+
"contributors" => contributors,
|
74
78
|
"publisher" => publisher,
|
75
79
|
"container" => container,
|
76
80
|
"date" => date,
|
@@ -26,7 +26,7 @@ module Commonmeta
|
|
26
26
|
|
27
27
|
type = 'Software'
|
28
28
|
|
29
|
-
|
29
|
+
contributors = get_authors(Array.wrap(meta.fetch('author', nil)))
|
30
30
|
license = hsh_to_spdx('rightsIdentifier' => meta.fetch('license', nil))
|
31
31
|
|
32
32
|
# container = if meta.fetch("container-title", nil).present?
|
@@ -71,7 +71,7 @@ module Commonmeta
|
|
71
71
|
# "doi" => doi_from_url(doi),
|
72
72
|
# "url" => normalize_id(meta.fetch("URL", nil)),
|
73
73
|
'titles' => [{ 'title' => meta.fetch('name', nil) }],
|
74
|
-
'
|
74
|
+
'contributors' => contributors,
|
75
75
|
# "contributors" => contributors,
|
76
76
|
# "container" => container,
|
77
77
|
# "publisher" => meta.fetch("publisher", nil),
|
@@ -41,7 +41,7 @@ module Commonmeta
|
|
41
41
|
'type' => type,
|
42
42
|
'url' => meta.fetch('UR', nil),
|
43
43
|
'titles' => meta.fetch('T1', nil).present? ? [{ 'title' => meta.fetch('T1', nil) }] : nil,
|
44
|
-
'
|
44
|
+
'contributors' => get_authors(author),
|
45
45
|
'publisher' => { 'name' => meta.fetch('PB', '(:unav)') },
|
46
46
|
'container' => container,
|
47
47
|
'date' => date,
|
@@ -106,8 +106,9 @@ module Commonmeta
|
|
106
106
|
additional_type = meta.fetch('additionalType', nil)
|
107
107
|
authors = meta.fetch('author', nil) || meta.fetch('creator', nil)
|
108
108
|
# Authors should be an object, if it's just a plain string don't try and parse it.
|
109
|
-
|
110
|
-
contributors =
|
109
|
+
contributors = get_authors(from_schema_org(Array.wrap(authors))) unless authors.is_a?(String)
|
110
|
+
contributors = [] if contributors.nil?
|
111
|
+
contributors += get_authors(from_schema_org(Array.wrap(meta.fetch('editor', nil))))
|
111
112
|
publisher = parse_attributes(meta.fetch('publisher', nil), content: 'name', first: true)
|
112
113
|
|
113
114
|
ct = schema_org == 'Dataset' ? 'includedInDataCatalog' : 'Periodical'
|
@@ -206,6 +207,8 @@ module Commonmeta
|
|
206
207
|
}.compact
|
207
208
|
end
|
208
209
|
|
210
|
+
files = Array.wrap(meta.fetch("contentUrl", nil)).map { |file| { "url" => file } }
|
211
|
+
|
209
212
|
# handle keywords as array and as comma-separated string
|
210
213
|
subjects = meta.fetch('keywords', nil)
|
211
214
|
subjects = subjects.to_s.split(', ') if subjects.is_a?(String)
|
@@ -221,7 +224,7 @@ module Commonmeta
|
|
221
224
|
'additional_type' => additional_type,
|
222
225
|
'alternate_identifiers' => alternate_identifiers.presence,
|
223
226
|
'url' => normalize_id(meta.fetch('url', nil)),
|
224
|
-
'
|
227
|
+
'files' => files.presence,
|
225
228
|
'sizes' => Array.wrap(meta.fetch('contenSize', nil)),
|
226
229
|
'formats' => Array.wrap(meta.fetch('encodingFormat',
|
227
230
|
nil) || meta.fetch('fileFormat', nil)),
|
@@ -230,7 +233,6 @@ module Commonmeta
|
|
230
233
|
else
|
231
234
|
[{ 'title' => meta.fetch('headline', nil) }]
|
232
235
|
end,
|
233
|
-
'creators' => creators,
|
234
236
|
'contributors' => contributors,
|
235
237
|
'publisher' => { 'name' => publisher },
|
236
238
|
'provider' => parse_attributes(meta.fetch('provider', nil), content: 'name', first: true),
|
@@ -5,7 +5,7 @@ require "pathname"
|
|
5
5
|
|
6
6
|
module Commonmeta
|
7
7
|
module SchemaUtils
|
8
|
-
COMMONMETA = File.read(File.expand_path("../../resources/commonmeta_v0.
|
8
|
+
COMMONMETA = File.read(File.expand_path("../../resources/commonmeta_v0.10.3.json",
|
9
9
|
__dir__))
|
10
10
|
|
11
11
|
def json_schema_errors
|
data/lib/commonmeta/utils.rb
CHANGED
@@ -869,7 +869,7 @@ module Commonmeta
|
|
869
869
|
end
|
870
870
|
|
871
871
|
def map_hash_keys(element: nil, mapping: nil)
|
872
|
-
Array.wrap(element).map do |a|
|
872
|
+
a = Array.wrap(element).map do |a|
|
873
873
|
a.map { |k, v| [mapping.fetch(k, k), v] }.reduce({}) do |hsh, (k, v)|
|
874
874
|
if k == "affiliation" && v.is_a?(Array)
|
875
875
|
hsh[k] = v.map do |affiliation|
|
@@ -883,6 +883,8 @@ module Commonmeta
|
|
883
883
|
elsif k == "type" && v.is_a?(String)
|
884
884
|
hsh[k] = v.capitalize
|
885
885
|
hsh
|
886
|
+
elsif k == "contributorRoles"
|
887
|
+
hsh
|
886
888
|
elsif v.is_a?(Hash)
|
887
889
|
hsh[k] = to_schema_org(v)
|
888
890
|
hsh
|
@@ -930,7 +932,7 @@ module Commonmeta
|
|
930
932
|
a["given"] = a["givenName"]
|
931
933
|
a["literal"] = a["name"] unless a["familyName"].present?
|
932
934
|
a.except("nameType", "type", "@type", "id", "@id", "name", "familyName", "givenName",
|
933
|
-
"affiliation", "
|
935
|
+
"affiliation", "contributorRoles").compact
|
934
936
|
end.presence
|
935
937
|
end
|
936
938
|
|
data/lib/commonmeta/version.rb
CHANGED
@@ -13,7 +13,7 @@ module Commonmeta
|
|
13
13
|
bibtex_key: normalize_id(id),
|
14
14
|
doi: doi_from_url(id),
|
15
15
|
url: url,
|
16
|
-
author: authors_as_string(
|
16
|
+
author: authors_as_string(contributors),
|
17
17
|
keywords: if subjects.present?
|
18
18
|
Array.wrap(subjects).map do |k|
|
19
19
|
parse_attributes(k, content: 'subject', first: true)
|
@@ -10,14 +10,15 @@ module Commonmeta
|
|
10
10
|
return nil unless %w[Software Collection].include?(type)
|
11
11
|
|
12
12
|
title = parse_attributes(titles, content: 'title', first: true)
|
13
|
-
|
13
|
+
authors = Array.wrap(contributors).select { |c| c['contributorRoles'] == ['Author'] }
|
14
|
+
|
14
15
|
hsh = {
|
15
16
|
'cff-version' => '1.2.0',
|
16
17
|
'message' => "If you use #{title} in your research, please cite it using the following metadata",
|
17
18
|
'doi' => normalize_doi(id),
|
18
19
|
'repository-code' => url,
|
19
20
|
'title' => title,
|
20
|
-
'authors' =>
|
21
|
+
'authors' => write_cff_contributors(authors),
|
21
22
|
'abstract' => parse_attributes(descriptions, content: 'description', first: true),
|
22
23
|
'version' => version,
|
23
24
|
'keywords' => if subjects.present?
|
@@ -34,8 +35,8 @@ module Commonmeta
|
|
34
35
|
hsh.to_yaml
|
35
36
|
end
|
36
37
|
|
37
|
-
def
|
38
|
-
Array.wrap(
|
38
|
+
def write_cff_contributors(contributors)
|
39
|
+
Array.wrap(contributors).map do |a|
|
39
40
|
if a['givenName'].present? || a['id'].present?
|
40
41
|
{ 'given-names' => a['givenName'],
|
41
42
|
'family-names' => a['familyName'],
|