briard 2.4.2 → 2.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/codeql-analysis.yml +72 -0
- data/.github/workflows/rubocop.yml +50 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +144 -620
- data/.rubocop_todo.yml +76 -0
- data/CHANGELOG.md +18 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +43 -9
- data/Rakefile +1 -1
- data/{bolognese.gemspec → briard.gemspec} +46 -39
- data/lib/briard/array.rb +2 -2
- data/lib/briard/author_utils.rb +79 -71
- data/lib/briard/cli.rb +12 -13
- data/lib/briard/crossref_utils.rb +73 -61
- data/lib/briard/datacite_utils.rb +132 -106
- data/lib/briard/doi_utils.rb +10 -10
- data/lib/briard/metadata.rb +96 -106
- data/lib/briard/metadata_utils.rb +87 -78
- data/lib/briard/readers/bibtex_reader.rb +65 -65
- data/lib/briard/readers/cff_reader.rb +88 -70
- data/lib/briard/readers/citeproc_reader.rb +90 -84
- data/lib/briard/readers/codemeta_reader.rb +68 -50
- data/lib/briard/readers/crosscite_reader.rb +2 -2
- data/lib/briard/readers/crossref_reader.rb +249 -210
- data/lib/briard/readers/datacite_json_reader.rb +3 -3
- data/lib/briard/readers/datacite_reader.rb +225 -189
- data/lib/briard/readers/npm_reader.rb +49 -42
- data/lib/briard/readers/ris_reader.rb +82 -80
- data/lib/briard/readers/schema_org_reader.rb +182 -159
- data/lib/briard/string.rb +1 -1
- data/lib/briard/utils.rb +4 -4
- data/lib/briard/version.rb +3 -1
- data/lib/briard/whitelist_scrubber.rb +11 -4
- data/lib/briard/writers/bibtex_writer.rb +14 -8
- data/lib/briard/writers/cff_writer.rb +33 -26
- data/lib/briard/writers/codemeta_writer.rb +19 -15
- data/lib/briard/writers/csv_writer.rb +6 -4
- data/lib/briard/writers/datacite_json_writer.rb +8 -2
- data/lib/briard/writers/jats_writer.rb +33 -28
- data/lib/briard/writers/rdf_xml_writer.rb +1 -1
- data/lib/briard/writers/ris_writer.rb +30 -18
- data/lib/briard/writers/turtle_writer.rb +1 -1
- data/lib/briard.rb +6 -6
- data/rubocop.sarif +0 -0
- data/spec/array_spec.rb +5 -5
- data/spec/author_utils_spec.rb +151 -132
- data/spec/datacite_utils_spec.rb +135 -83
- data/spec/doi_utils_spec.rb +168 -164
- data/spec/find_from_format_spec.rb +69 -69
- data/spec/fixtures/vcr_cassettes/Briard_Metadata/sanitize/onlies_keep_specific_tags.yml +65 -0
- data/spec/fixtures/vcr_cassettes/Briard_Metadata/sanitize/removes_a_tags.yml +65 -0
- data/spec/metadata_spec.rb +91 -90
- data/spec/readers/bibtex_reader_spec.rb +43 -38
- data/spec/readers/cff_reader_spec.rb +165 -153
- data/spec/readers/citeproc_reader_spec.rb +45 -40
- data/spec/readers/codemeta_reader_spec.rb +128 -115
- data/spec/readers/crosscite_reader_spec.rb +34 -24
- data/spec/readers/crossref_reader_spec.rb +1098 -939
- data/spec/readers/datacite_json_reader_spec.rb +53 -40
- data/spec/readers/datacite_reader_spec.rb +1541 -1337
- data/spec/readers/npm_reader_spec.rb +48 -43
- data/spec/readers/ris_reader_spec.rb +53 -47
- data/spec/readers/schema_org_reader_spec.rb +329 -267
- data/spec/spec_helper.rb +6 -5
- data/spec/utils_spec.rb +371 -347
- data/spec/writers/bibtex_writer_spec.rb +143 -143
- data/spec/writers/cff_writer_spec.rb +96 -90
- data/spec/writers/citation_writer_spec.rb +34 -33
- data/spec/writers/citeproc_writer_spec.rb +226 -224
- data/spec/writers/codemeta_writer_spec.rb +18 -16
- data/spec/writers/crosscite_writer_spec.rb +91 -73
- data/spec/writers/crossref_writer_spec.rb +99 -91
- data/spec/writers/csv_writer_spec.rb +70 -70
- data/spec/writers/datacite_json_writer_spec.rb +78 -68
- data/spec/writers/datacite_writer_spec.rb +417 -322
- data/spec/writers/jats_writer_spec.rb +177 -161
- data/spec/writers/rdf_xml_writer_spec.rb +68 -63
- data/spec/writers/ris_writer_spec.rb +162 -162
- data/spec/writers/schema_org_writer_spec.rb +329 -294
- data/spec/writers/turtle_writer_spec.rb +47 -47
- metadata +242 -166
- data/.github/workflows/release.yml +0 -47
@@ -3,97 +3,97 @@
|
|
3
3
|
module Briard
|
4
4
|
module Readers
|
5
5
|
module BibtexReader
|
6
|
-
BIB_TO_CP_TRANSLATIONS = {
|
7
|
-
"article" => "article-journal",
|
8
|
-
"phdthesis" => "thesis"
|
9
|
-
}
|
6
|
+
BIB_TO_CP_TRANSLATIONS = { 'article' => 'article-journal', 'phdthesis' => 'thesis' }.freeze
|
10
7
|
|
11
8
|
BIB_TO_RIS_TRANSLATIONS = {
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
}
|
9
|
+
'article' => 'JOUR',
|
10
|
+
'book' => 'BOOK',
|
11
|
+
'inbook' => 'CHAP',
|
12
|
+
'inproceedings' => 'CPAPER',
|
13
|
+
'manual' => nil,
|
14
|
+
'misc' => 'GEN',
|
15
|
+
'phdthesis' => 'THES',
|
16
|
+
'proceedings' => 'CONF',
|
17
|
+
'techreport' => 'RPRT',
|
18
|
+
'unpublished' => 'UNPD'
|
19
|
+
}.freeze
|
23
20
|
|
24
|
-
BIB_TO_SO_TRANSLATIONS = {
|
25
|
-
"article" => "ScholarlyArticle",
|
26
|
-
"phdthesis" => "Thesis"
|
27
|
-
}
|
21
|
+
BIB_TO_SO_TRANSLATIONS = { 'article' => 'ScholarlyArticle', 'phdthesis' => 'Thesis' }.freeze
|
28
22
|
|
29
23
|
def read_bibtex(string: nil, **options)
|
30
|
-
read_options = ActiveSupport::HashWithIndifferentAccess.new(options.except(:doi, :id, :url,
|
24
|
+
read_options = ActiveSupport::HashWithIndifferentAccess.new(options.except(:doi, :id, :url,
|
25
|
+
:sandbox, :validate, :ra))
|
31
26
|
|
32
27
|
meta = string.present? ? BibTeX.parse(string).first : OpenStruct.new
|
33
28
|
|
34
29
|
bibtex_type = meta.try(:type).to_s
|
35
|
-
schema_org = BIB_TO_SO_TRANSLATIONS[bibtex_type] ||
|
30
|
+
schema_org = BIB_TO_SO_TRANSLATIONS[bibtex_type] || 'ScholarlyArticle'
|
36
31
|
types = {
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
32
|
+
'resourceTypeGeneral' => Metadata::BIB_TO_DC_TRANSLATIONS[bibtex_type],
|
33
|
+
'resourceType' => Briard::Utils::BIB_TO_CR_TRANSLATIONS[meta.try(:type).to_s] || meta.try(:type).to_s,
|
34
|
+
'schemaOrg' => schema_org,
|
35
|
+
'bibtex' => bibtex_type,
|
36
|
+
'citeproc' => BIB_TO_CP_TRANSLATIONS[meta.try(:type).to_s] || 'misc',
|
37
|
+
'ris' => BIB_TO_RIS_TRANSLATIONS[meta.try(:type).to_s] || 'GEN'
|
43
38
|
}.compact
|
44
39
|
doi = meta.try(:doi).to_s.presence || options[:doi]
|
45
40
|
|
46
41
|
creators = Array(meta.try(:author)).map do |a|
|
47
|
-
{
|
48
|
-
|
49
|
-
|
50
|
-
|
42
|
+
{ 'nameType' => 'Personal',
|
43
|
+
'name' => [a.last, a.first].join(', '),
|
44
|
+
'givenName' => a.first,
|
45
|
+
'familyName' => a.last }.compact
|
51
46
|
end
|
52
47
|
|
53
48
|
related_identifiers = if meta.try(:journal).present? && meta.try(:issn).to_s.presence
|
54
|
-
[{
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
49
|
+
[{ 'type' => 'Periodical',
|
50
|
+
'relationType' => 'IsPartOf',
|
51
|
+
'relatedIdentifierType' => 'ISSN',
|
52
|
+
'title' => meta.journal.to_s,
|
53
|
+
'relatedIdentifier' => meta.try(:issn).to_s.presence }.compact]
|
59
54
|
end
|
60
55
|
|
61
56
|
container = if meta.try(:journal).present?
|
62
|
-
first_page = meta.try(:pages).present? ? meta.try(:pages).split(
|
63
|
-
last_page = meta.try(:pages).present? ? meta.try(:pages).split(
|
57
|
+
first_page = meta.try(:pages).present? ? meta.try(:pages).split('-').map(&:strip)[0] : nil
|
58
|
+
last_page = meta.try(:pages).present? ? meta.try(:pages).split('-').map(&:strip)[1] : nil
|
64
59
|
|
65
|
-
{
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
60
|
+
{ 'type' => 'Journal',
|
61
|
+
'title' => meta.journal.to_s,
|
62
|
+
'identifier' => meta.try(:issn).to_s.presence,
|
63
|
+
'identifierType' => meta.try(:issn).present? ? 'ISSN' : nil,
|
64
|
+
'volume' => meta.try(:volume).to_s.presence,
|
65
|
+
'firstPage' => first_page,
|
66
|
+
'lastPage' => last_page }.compact
|
72
67
|
end
|
73
68
|
|
74
|
-
state = meta.try(:doi).to_s.present? || read_options.present? ?
|
69
|
+
state = meta.try(:doi).to_s.present? || read_options.present? ? 'findable' : 'not_found'
|
75
70
|
dates = if meta.try(:date).present? && Date.edtf(meta.date.to_s).present?
|
76
|
-
[{
|
77
|
-
|
71
|
+
[{ 'date' => meta.date.to_s,
|
72
|
+
'dateType' => 'Issued' }]
|
78
73
|
end
|
79
|
-
publication_year =
|
80
|
-
rights_list = meta.try(:copyright).present? ? [hsh_to_spdx(
|
74
|
+
publication_year = meta.try(:date).present? ? meta.date.to_s[0..3] : nil
|
75
|
+
rights_list = meta.try(:copyright).present? ? [hsh_to_spdx('rightsURI' => meta[:copyright])] : []
|
81
76
|
|
82
|
-
{
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
77
|
+
{ 'id' => normalize_doi(doi),
|
78
|
+
'types' => types,
|
79
|
+
'doi' => doi,
|
80
|
+
'url' => meta.try(:url).to_s.presence,
|
81
|
+
'titles' => meta.try(:title).present? ? [{ 'title' => meta.try(:title).to_s }] : [],
|
82
|
+
'creators' => creators,
|
83
|
+
'container' => container,
|
84
|
+
'publisher' => meta.try(:publisher).to_s.presence,
|
85
|
+
'related_identifiers' => related_identifiers,
|
86
|
+
'dates' => dates,
|
87
|
+
'publication_year' => publication_year,
|
88
|
+
'descriptions' => if meta.try(:abstract).present?
|
89
|
+
[{
|
90
|
+
'description' => meta.try(:abstract) && sanitize(meta.abstract.to_s).presence, 'descriptionType' => 'Abstract'
|
91
|
+
}]
|
92
|
+
else
|
93
|
+
[]
|
94
|
+
end,
|
95
|
+
'rights_list' => rights_list,
|
96
|
+
'state' => state }.merge(read_options)
|
97
97
|
end
|
98
98
|
end
|
99
99
|
end
|
@@ -3,119 +3,137 @@
|
|
3
3
|
module Briard
|
4
4
|
module Readers
|
5
5
|
module CffReader
|
6
|
-
def get_cff(id: nil, **
|
7
|
-
return {
|
6
|
+
def get_cff(id: nil, **_options)
|
7
|
+
return { 'string' => nil, 'state' => 'not_found' } unless id.present?
|
8
|
+
|
8
9
|
id = normalize_id(id)
|
9
|
-
response = Maremma.get(github_as_cff_url(id), accept:
|
10
|
-
data = response.body.fetch(
|
10
|
+
response = Maremma.get(github_as_cff_url(id), accept: 'json', raw: true)
|
11
|
+
data = response.body.fetch('data', nil)
|
11
12
|
# Dates are parsed to date object, need to convert to iso8601 later
|
12
13
|
string = Psych.safe_load(data, permitted_classes: [Date])
|
13
|
-
{
|
14
|
+
{ 'string' => string }
|
14
15
|
end
|
15
16
|
|
16
17
|
def read_cff(string: nil, **options)
|
17
|
-
read_options = ActiveSupport::HashWithIndifferentAccess.new(options.except(:doi, :id, :url,
|
18
|
+
read_options = ActiveSupport::HashWithIndifferentAccess.new(options.except(:doi, :id, :url,
|
19
|
+
:sandbox, :validate, :ra))
|
18
20
|
meta = string.is_a?(String) ? Psych.safe_load(string, permitted_classes: [Date]) : string
|
19
21
|
|
20
|
-
identifiers = Array.wrap(meta.fetch(
|
22
|
+
identifiers = Array.wrap(meta.fetch('identifiers', nil)).map do |r|
|
21
23
|
r = normalize_id(r) if r.is_a?(String)
|
22
|
-
if r.is_a?(String) &&
|
23
|
-
|
24
|
+
if r.is_a?(String) && URI(r).host != 'doi.org'
|
25
|
+
{ 'identifierType' => 'URL', 'identifier' => r }
|
24
26
|
elsif r.is_a?(Hash)
|
25
|
-
{
|
27
|
+
{ 'identifierType' => get_identifier_type(r['propertyID']), 'identifier' => r['value'] }
|
26
28
|
end
|
27
29
|
end.compact.uniq
|
28
30
|
|
29
|
-
id = normalize_id(options[:doi] || meta.fetch(
|
30
|
-
|
31
|
-
|
31
|
+
id = normalize_id(options[:doi] || meta.fetch('doi',
|
32
|
+
nil) || Array.wrap(meta.fetch('identifiers', nil)).find do |i|
|
33
|
+
i['type'] == 'doi'
|
34
|
+
end.fetch('value', nil))
|
35
|
+
url = normalize_id(meta.fetch('repository-code', nil))
|
36
|
+
creators = cff_creators(Array.wrap(meta.fetch('authors', nil)))
|
32
37
|
|
33
38
|
dates = []
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
39
|
+
if meta.fetch('date-released', nil).present?
|
40
|
+
dates << { 'date' => meta.fetch('date-released', nil).iso8601, 'dateType' => 'Issued' }
|
41
|
+
end
|
42
|
+
publication_year = meta.fetch('date-released').iso8601[0..3] if meta.fetch('date-released',
|
43
|
+
nil).present?
|
44
|
+
publisher = url.to_s.starts_with?('https://github.com') ? 'GitHub' : nil
|
45
|
+
state = meta.present? || read_options.present? ? 'findable' : 'not_found'
|
38
46
|
types = {
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
47
|
+
'resourceTypeGeneral' => 'Software',
|
48
|
+
'resourceType' => nil,
|
49
|
+
'schemaOrg' => 'SoftwareSourceCode',
|
50
|
+
'citeproc' => 'article-journal',
|
51
|
+
'bibtex' => 'misc',
|
52
|
+
'ris' => 'COMP'
|
45
53
|
}.compact
|
46
|
-
subjects = Array.wrap(meta.fetch(
|
54
|
+
subjects = Array.wrap(meta.fetch('keywords', nil)).reduce([]) do |sum, subject|
|
47
55
|
sum += name_to_fos(subject)
|
48
56
|
|
49
57
|
sum
|
50
58
|
end
|
51
59
|
|
52
|
-
titles =
|
53
|
-
|
54
|
-
|
60
|
+
titles = if meta.fetch('title', nil).present?
|
61
|
+
[{ 'title' => meta.fetch('title', nil) }]
|
62
|
+
else
|
63
|
+
[]
|
64
|
+
end
|
65
|
+
related_identifiers = Array.wrap(cff_references(meta.fetch('references', nil)))
|
66
|
+
rights_list = if meta.fetch('license', nil).present?
|
67
|
+
[hsh_to_spdx('rightsIdentifier' => meta.fetch('license'))]
|
68
|
+
end
|
55
69
|
|
56
|
-
{
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
70
|
+
{ 'id' => id,
|
71
|
+
'types' => types,
|
72
|
+
'identifiers' => identifiers,
|
73
|
+
'doi' => doi_from_url(id),
|
74
|
+
'url' => url,
|
75
|
+
'titles' => titles,
|
76
|
+
'creators' => creators,
|
77
|
+
'publisher' => publisher,
|
78
|
+
'related_identifiers' => related_identifiers,
|
79
|
+
'dates' => dates,
|
80
|
+
'publication_year' => publication_year,
|
81
|
+
'descriptions' => if meta.fetch('abstract', nil).present?
|
82
|
+
[{ 'description' => sanitize(meta.fetch('abstract')),
|
83
|
+
'descriptionType' => 'Abstract' }]
|
84
|
+
end,
|
85
|
+
'rights_list' => rights_list,
|
86
|
+
'version_info' => meta.fetch('version', nil),
|
87
|
+
'subjects' => subjects,
|
88
|
+
'state' => state }.merge(read_options)
|
73
89
|
end
|
74
90
|
|
75
91
|
def cff_creators(creators)
|
76
92
|
Array.wrap(creators).map do |a|
|
77
|
-
name_identifiers = normalize_orcid(parse_attributes(a[
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
93
|
+
name_identifiers = if normalize_orcid(parse_attributes(a['orcid'])).present?
|
94
|
+
[{
|
95
|
+
'nameIdentifier' => normalize_orcid(parse_attributes(a['orcid'])), 'nameIdentifierScheme' => 'ORCID', 'schemeUri' => 'https://orcid.org'
|
96
|
+
}]
|
97
|
+
end
|
98
|
+
if a['given-names'].present? || a['family-names'].present? || name_identifiers.present?
|
99
|
+
given_name = parse_attributes(a['given-names'])
|
100
|
+
family_name = parse_attributes(a['family-names'])
|
101
|
+
affiliation = Array.wrap(a['affiliation']).map do |a|
|
82
102
|
if a.is_a?(Hash)
|
83
103
|
a
|
84
|
-
elsif a.is_a?(Hash) && a.key?(
|
104
|
+
elsif a.is_a?(Hash) && a.key?('__content__') && a['__content__'].strip.blank?
|
85
105
|
nil
|
86
|
-
elsif a.is_a?(Hash) && a.key?(
|
87
|
-
{
|
106
|
+
elsif a.is_a?(Hash) && a.key?('__content__')
|
107
|
+
{ 'name' => a['__content__'] }
|
88
108
|
elsif a.strip.blank?
|
89
109
|
nil
|
90
110
|
elsif a.is_a?(String)
|
91
|
-
{
|
111
|
+
{ 'name' => a }
|
92
112
|
end
|
93
113
|
end.compact
|
94
114
|
|
95
|
-
{
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
115
|
+
{ 'nameType' => 'Personal',
|
116
|
+
'nameIdentifiers' => name_identifiers,
|
117
|
+
'name' => [family_name, given_name].compact.join(', '),
|
118
|
+
'givenName' => given_name,
|
119
|
+
'familyName' => family_name,
|
120
|
+
'affiliation' => affiliation.presence }.compact
|
101
121
|
else
|
102
|
-
{
|
103
|
-
|
122
|
+
{ 'nameType' => 'Organizational',
|
123
|
+
'name' => a['name'] || a['__content__'] }
|
104
124
|
end
|
105
125
|
end
|
106
126
|
end
|
107
127
|
|
108
128
|
def cff_references(references)
|
109
129
|
Array.wrap(references).map do |r|
|
110
|
-
identifier = Array.wrap(r[
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
nil
|
118
|
-
end
|
130
|
+
identifier = Array.wrap(r['identifiers']).find { |i| i['type'] == 'doi' }
|
131
|
+
|
132
|
+
next unless identifier.present?
|
133
|
+
|
134
|
+
{ 'relatedIdentifier' => normalize_id(parse_attributes(identifier['value'])),
|
135
|
+
'relationType' => 'References',
|
136
|
+
'relatedIdentifierType' => 'DOI' }.compact
|
119
137
|
end.compact.unwrap
|
120
138
|
end
|
121
139
|
end
|
@@ -4,115 +4,121 @@ module Briard
|
|
4
4
|
module Readers
|
5
5
|
module CiteprocReader
|
6
6
|
CP_TO_SO_TRANSLATIONS = {
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
}
|
7
|
+
'song' => 'AudioObject',
|
8
|
+
'post-weblog' => 'BlogPosting',
|
9
|
+
'dataset' => 'Dataset',
|
10
|
+
'graphic' => 'ImageObject',
|
11
|
+
'motion_picture' => 'Movie',
|
12
|
+
'article-journal' => 'ScholarlyArticle',
|
13
|
+
'broadcast' => 'VideoObject',
|
14
|
+
'webpage' => 'WebPage'
|
15
|
+
}.freeze
|
16
16
|
|
17
17
|
CP_TO_RIS_TRANSLATIONS = {
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
}
|
18
|
+
'post-weblog' => 'BLOG',
|
19
|
+
'dataset' => 'DATA',
|
20
|
+
'graphic' => 'FIGURE',
|
21
|
+
'book' => 'BOOK',
|
22
|
+
'motion_picture' => 'MPCT',
|
23
|
+
'article-journal' => 'JOUR',
|
24
|
+
'broadcast' => 'MPCT',
|
25
|
+
'webpage' => 'ELEC'
|
26
|
+
}.freeze
|
27
27
|
|
28
28
|
def read_citeproc(string: nil, **options)
|
29
29
|
if string.present?
|
30
30
|
errors = jsonlint(string)
|
31
|
-
return {
|
31
|
+
return { 'errors' => errors } if errors.present?
|
32
32
|
end
|
33
33
|
|
34
|
-
read_options = ActiveSupport::HashWithIndifferentAccess.new(options.except(:doi, :id, :url,
|
34
|
+
read_options = ActiveSupport::HashWithIndifferentAccess.new(options.except(:doi, :id, :url,
|
35
|
+
:sandbox, :validate, :ra))
|
35
36
|
|
36
37
|
meta = string.present? ? Maremma.from_json(string) : {}
|
37
38
|
|
38
|
-
citeproc_type = meta.fetch(
|
39
|
-
schema_org = CP_TO_SO_TRANSLATIONS[citeproc_type] ||
|
39
|
+
citeproc_type = meta.fetch('type', nil)
|
40
|
+
schema_org = CP_TO_SO_TRANSLATIONS[citeproc_type] || 'CreativeWork'
|
40
41
|
types = {
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
42
|
+
'resourceTypeGeneral' => Briard::Utils::CP_TO_DC_TRANSLATIONS[citeproc_type],
|
43
|
+
'reourceType' => meta.fetch('additionalType', nil),
|
44
|
+
'schemaOrg' => schema_org,
|
45
|
+
'citeproc' => citeproc_type,
|
46
|
+
'bibtex' => Briard::Utils::SO_TO_BIB_TRANSLATIONS[schema_org] || 'misc',
|
47
|
+
'ris' => CP_TO_RIS_TRANSLATIONS[schema_org] || 'GEN'
|
47
48
|
}.compact
|
48
49
|
|
49
|
-
creators = if meta.fetch(
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
contributors = get_authors(from_citeproc(Array.wrap(meta.fetch(
|
55
|
-
dates = if date = get_date_from_date_parts(meta.fetch(
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
50
|
+
creators = if meta.fetch('author', nil).present?
|
51
|
+
get_authors(from_citeproc(Array.wrap(meta.fetch('author', nil))))
|
52
|
+
else
|
53
|
+
[{ 'nameType' => 'Organizational', 'name' => ':(unav)' }]
|
54
|
+
end
|
55
|
+
contributors = get_authors(from_citeproc(Array.wrap(meta.fetch('editor', nil))))
|
56
|
+
dates = if (date = get_date_from_date_parts(meta.fetch('issued',
|
57
|
+
nil))) && Date.edtf(date).present?
|
58
|
+
[{ 'date' => date,
|
59
|
+
'dateType' => 'Issued' }]
|
60
60
|
end
|
61
|
-
publication_year = get_date_from_date_parts(meta.fetch(
|
62
|
-
rights_list = if meta.fetch(
|
63
|
-
[hsh_to_spdx(
|
61
|
+
publication_year = get_date_from_date_parts(meta.fetch('issued', nil)).to_s[0..3]
|
62
|
+
rights_list = if meta.fetch('copyright', nil)
|
63
|
+
[hsh_to_spdx('rightsURI' => meta.fetch('copyright'))]
|
64
64
|
end
|
65
|
-
related_identifiers = if meta.fetch(
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
65
|
+
related_identifiers = if meta.fetch('container-title',
|
66
|
+
nil).present? && meta.fetch('ISSN', nil).present?
|
67
|
+
[{ 'type' => 'Periodical',
|
68
|
+
'relationType' => 'IsPartOf',
|
69
|
+
'relatedIdentifierType' => 'ISSN',
|
70
|
+
'title' => meta.fetch('container-title', nil),
|
71
|
+
'relatedIdentifier' => meta.fetch('ISSN', nil) }.compact]
|
71
72
|
end
|
72
|
-
container = if meta.fetch(
|
73
|
-
|
74
|
-
|
73
|
+
container = if meta.fetch('container-title', nil).present?
|
74
|
+
first_page = if meta.fetch('page', nil).present?
|
75
|
+
meta.fetch('page').split('-').map(&:strip)[0]
|
76
|
+
end
|
77
|
+
last_page = if meta.fetch('page', nil).present?
|
78
|
+
meta.fetch('page').split('-').map(&:strip)[1]
|
79
|
+
end
|
75
80
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
else
|
86
|
-
nil
|
87
|
-
end
|
81
|
+
{ 'type' => 'Periodical',
|
82
|
+
'title' => meta.fetch('container-title', nil),
|
83
|
+
'identifier' => meta.fetch('ISSN', nil),
|
84
|
+
'identifierType' => meta.fetch('ISSN', nil).present? ? 'ISSN' : nil,
|
85
|
+
'volume' => meta.fetch('volume', nil),
|
86
|
+
'issue' => meta.fetch('issue', nil),
|
87
|
+
'firstPage' => first_page,
|
88
|
+
'lastPage' => last_page }.compact
|
89
|
+
end
|
88
90
|
|
89
|
-
id = normalize_id(meta.fetch(
|
91
|
+
id = normalize_id(meta.fetch('id', nil) || meta.fetch('DOI', nil))
|
90
92
|
|
91
|
-
state = id.present? || read_options.present? ?
|
92
|
-
subjects = Array.wrap(meta.fetch(
|
93
|
+
state = id.present? || read_options.present? ? 'findable' : 'not_found'
|
94
|
+
subjects = Array.wrap(meta.fetch('categories', nil)).reduce([]) do |sum, subject|
|
93
95
|
sum += name_to_fos(subject)
|
94
96
|
|
95
97
|
sum
|
96
98
|
end
|
97
99
|
|
98
|
-
{
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
100
|
+
{ 'id' => id,
|
101
|
+
'types' => types,
|
102
|
+
'doi' => doi_from_url(id),
|
103
|
+
'url' => normalize_id(meta.fetch('URL', nil)),
|
104
|
+
'titles' => [{ 'title' => meta.fetch('title', nil) }],
|
105
|
+
'creators' => creators,
|
106
|
+
'contributors' => contributors,
|
107
|
+
'container' => container,
|
108
|
+
'publisher' => meta.fetch('publisher', nil),
|
109
|
+
'related_identifiers' => related_identifiers,
|
110
|
+
'dates' => dates,
|
111
|
+
'publication_year' => publication_year,
|
112
|
+
'descriptions' => if meta.fetch('abstract', nil).present?
|
113
|
+
[{ 'description' => sanitize(meta.fetch('abstract')),
|
114
|
+
'descriptionType' => 'Abstract' }]
|
115
|
+
else
|
116
|
+
[]
|
117
|
+
end,
|
118
|
+
'rights_list' => rights_list,
|
119
|
+
'version_info' => meta.fetch('version', nil),
|
120
|
+
'subjects' => subjects,
|
121
|
+
'state' => state }.merge(read_options)
|
116
122
|
end
|
117
123
|
end
|
118
124
|
end
|