sul_orcid_client 0.4.1 → 0.5.0
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/.rubocop.yml +353 -13
- data/Gemfile +2 -2
- data/Gemfile.lock +115 -112
- data/README.md +1 -2
- data/Rakefile +3 -3
- data/lib/sul_orcid_client/cocina_support.rb +9 -5
- data/lib/sul_orcid_client/contributor_mapper.rb +28 -25
- data/lib/sul_orcid_client/version.rb +1 -1
- data/lib/sul_orcid_client/work_mapper.rb +66 -59
- data/lib/sul_orcid_client.rb +44 -32
- data/sul_orcid_client.gemspec +32 -28
- metadata +61 -16
- data/.rubocop/custom.yml +0 -85
- data/.standard.yml +0 -1
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
sul_orcid_client (0.
|
5
|
-
activesupport (>= 4.2
|
4
|
+
sul_orcid_client (0.5.0)
|
5
|
+
activesupport (>= 4.2)
|
6
6
|
cocina-models (~> 0.90)
|
7
7
|
faraday
|
8
8
|
faraday-retry
|
@@ -12,24 +12,28 @@ PATH
|
|
12
12
|
GEM
|
13
13
|
remote: https://rubygems.org/
|
14
14
|
specs:
|
15
|
-
activesupport (
|
15
|
+
activesupport (8.0.1)
|
16
16
|
base64
|
17
|
+
benchmark (>= 0.3)
|
17
18
|
bigdecimal
|
18
|
-
concurrent-ruby (~> 1.0, >= 1.
|
19
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
19
20
|
connection_pool (>= 2.2.5)
|
20
21
|
drb
|
21
22
|
i18n (>= 1.6, < 2)
|
23
|
+
logger (>= 1.4.2)
|
22
24
|
minitest (>= 5.1)
|
23
|
-
|
24
|
-
tzinfo (~> 2.0)
|
25
|
-
|
26
|
-
|
25
|
+
securerandom (>= 0.3)
|
26
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
27
|
+
uri (>= 0.13.1)
|
28
|
+
addressable (2.8.7)
|
29
|
+
public_suffix (>= 2.0.2, < 7.0)
|
27
30
|
ast (2.4.2)
|
28
31
|
attr_extras (7.1.0)
|
29
32
|
base64 (0.2.0)
|
30
|
-
|
33
|
+
benchmark (0.4.0)
|
34
|
+
bigdecimal (3.1.9)
|
31
35
|
byebug (11.1.3)
|
32
|
-
cocina-models (0.
|
36
|
+
cocina-models (0.99.4)
|
33
37
|
activesupport
|
34
38
|
deprecation
|
35
39
|
dry-struct (~> 1.0)
|
@@ -39,71 +43,77 @@ GEM
|
|
39
43
|
i18n
|
40
44
|
jsonpath
|
41
45
|
nokogiri
|
42
|
-
openapi3_parser
|
43
46
|
openapi_parser (~> 1.0)
|
44
|
-
rss
|
45
47
|
super_diff
|
46
48
|
thor
|
47
49
|
zeitwerk (~> 2.1)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
50
|
+
concurrent-ruby (1.3.5)
|
51
|
+
connection_pool (2.5.0)
|
52
|
+
crack (1.0.0)
|
53
|
+
bigdecimal
|
52
54
|
rexml
|
53
55
|
deprecation (1.1.0)
|
54
56
|
activesupport
|
55
|
-
diff-lcs (1.5.
|
56
|
-
docile (1.4.
|
57
|
-
drb (2.2.
|
58
|
-
|
59
|
-
dry-core (1.0.1)
|
57
|
+
diff-lcs (1.5.1)
|
58
|
+
docile (1.4.1)
|
59
|
+
drb (2.2.1)
|
60
|
+
dry-core (1.1.0)
|
60
61
|
concurrent-ruby (~> 1.0)
|
62
|
+
logger
|
61
63
|
zeitwerk (~> 2.6)
|
62
|
-
dry-inflector (1.
|
63
|
-
dry-logic (1.
|
64
|
+
dry-inflector (1.2.0)
|
65
|
+
dry-logic (1.6.0)
|
66
|
+
bigdecimal
|
64
67
|
concurrent-ruby (~> 1.0)
|
65
|
-
dry-core (~> 1.
|
68
|
+
dry-core (~> 1.1)
|
66
69
|
zeitwerk (~> 2.6)
|
67
|
-
dry-struct (1.
|
68
|
-
dry-core (~> 1.
|
69
|
-
dry-types (
|
70
|
+
dry-struct (1.7.1)
|
71
|
+
dry-core (~> 1.1)
|
72
|
+
dry-types (~> 1.8, >= 1.8.2)
|
70
73
|
ice_nine (~> 0.11)
|
71
74
|
zeitwerk (~> 2.6)
|
72
|
-
dry-types (1.
|
75
|
+
dry-types (1.8.2)
|
76
|
+
bigdecimal (~> 3.0)
|
73
77
|
concurrent-ruby (~> 1.0)
|
74
78
|
dry-core (~> 1.0)
|
75
79
|
dry-inflector (~> 1.0)
|
76
80
|
dry-logic (~> 1.4)
|
77
81
|
zeitwerk (~> 2.6)
|
78
|
-
edtf (3.
|
79
|
-
activesupport (>= 3.0, <
|
82
|
+
edtf (3.2.0)
|
83
|
+
activesupport (>= 3.0, < 9.0)
|
80
84
|
equivalent-xml (0.6.0)
|
81
85
|
nokogiri (>= 1.4.3)
|
82
|
-
faraday (2.
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
faraday-net_http (3.0
|
87
|
-
|
86
|
+
faraday (2.12.2)
|
87
|
+
faraday-net_http (>= 2.0, < 3.5)
|
88
|
+
json
|
89
|
+
logger
|
90
|
+
faraday-net_http (3.4.0)
|
91
|
+
net-http (>= 0.5.0)
|
92
|
+
faraday-retry (2.2.1)
|
88
93
|
faraday (~> 2.0)
|
89
|
-
hashdiff (1.
|
94
|
+
hashdiff (1.1.2)
|
90
95
|
hashie (5.0.0)
|
91
|
-
i18n (1.14.
|
96
|
+
i18n (1.14.7)
|
92
97
|
concurrent-ruby (~> 1.0)
|
93
98
|
ice_nine (0.11.2)
|
94
|
-
json (2.
|
99
|
+
json (2.9.1)
|
95
100
|
jsonpath (1.1.5)
|
96
101
|
multi_json
|
97
|
-
jwt (2.
|
98
|
-
|
99
|
-
|
100
|
-
|
102
|
+
jwt (2.10.1)
|
103
|
+
base64
|
104
|
+
language_server-protocol (3.17.0.4)
|
105
|
+
logger (1.6.6)
|
106
|
+
minitest (5.25.4)
|
101
107
|
multi_json (1.15.0)
|
102
|
-
multi_xml (0.
|
103
|
-
|
104
|
-
|
108
|
+
multi_xml (0.7.1)
|
109
|
+
bigdecimal (~> 3.1)
|
110
|
+
net-http (0.6.0)
|
111
|
+
uri
|
112
|
+
nokogiri (1.18.2-arm64-darwin)
|
105
113
|
racc (~> 1.4)
|
106
|
-
nokogiri (1.
|
114
|
+
nokogiri (1.18.2-x86_64-darwin)
|
115
|
+
racc (~> 1.4)
|
116
|
+
nokogiri (1.18.2-x86_64-linux-gnu)
|
107
117
|
racc (~> 1.4)
|
108
118
|
oauth2 (2.0.9)
|
109
119
|
faraday (>= 0.17.3, < 3.0)
|
@@ -112,102 +122,91 @@ GEM
|
|
112
122
|
rack (>= 1.2, < 4)
|
113
123
|
snaky_hash (~> 2.0)
|
114
124
|
version_gem (~> 1.1)
|
115
|
-
openapi3_parser (0.9.2)
|
116
|
-
commonmarker (~> 0.17)
|
117
125
|
openapi_parser (1.0.0)
|
118
|
-
optimist (3.
|
119
|
-
parallel (1.
|
120
|
-
parser (3.
|
126
|
+
optimist (3.2.0)
|
127
|
+
parallel (1.26.3)
|
128
|
+
parser (3.3.7.1)
|
121
129
|
ast (~> 2.4.1)
|
122
130
|
racc
|
123
131
|
patience_diff (1.2.0)
|
124
132
|
optimist (~> 3.0)
|
125
|
-
public_suffix (
|
126
|
-
racc (1.
|
127
|
-
rack (3.
|
133
|
+
public_suffix (6.0.1)
|
134
|
+
racc (1.8.1)
|
135
|
+
rack (3.1.9)
|
128
136
|
rainbow (3.1.1)
|
129
|
-
rake (13.1
|
130
|
-
regexp_parser (2.
|
131
|
-
rexml (3.
|
132
|
-
rspec (3.
|
133
|
-
rspec-core (~> 3.
|
134
|
-
rspec-expectations (~> 3.
|
135
|
-
rspec-mocks (~> 3.
|
136
|
-
rspec-core (3.
|
137
|
-
rspec-support (~> 3.
|
138
|
-
rspec-expectations (3.
|
137
|
+
rake (13.2.1)
|
138
|
+
regexp_parser (2.10.0)
|
139
|
+
rexml (3.4.0)
|
140
|
+
rspec (3.13.0)
|
141
|
+
rspec-core (~> 3.13.0)
|
142
|
+
rspec-expectations (~> 3.13.0)
|
143
|
+
rspec-mocks (~> 3.13.0)
|
144
|
+
rspec-core (3.13.3)
|
145
|
+
rspec-support (~> 3.13.0)
|
146
|
+
rspec-expectations (3.13.3)
|
139
147
|
diff-lcs (>= 1.2.0, < 2.0)
|
140
|
-
rspec-support (~> 3.
|
141
|
-
rspec-mocks (3.
|
148
|
+
rspec-support (~> 3.13.0)
|
149
|
+
rspec-mocks (3.13.2)
|
142
150
|
diff-lcs (>= 1.2.0, < 2.0)
|
143
|
-
rspec-support (~> 3.
|
144
|
-
rspec-support (3.
|
145
|
-
|
146
|
-
rexml
|
147
|
-
rubocop (1.57.2)
|
151
|
+
rspec-support (~> 3.13.0)
|
152
|
+
rspec-support (3.13.2)
|
153
|
+
rubocop (1.71.2)
|
148
154
|
json (~> 2.3)
|
149
155
|
language_server-protocol (>= 3.17.0)
|
150
156
|
parallel (~> 1.10)
|
151
|
-
parser (>= 3.
|
157
|
+
parser (>= 3.3.0.2)
|
152
158
|
rainbow (>= 2.2.2, < 4.0)
|
153
|
-
regexp_parser (>=
|
154
|
-
|
155
|
-
rubocop-ast (>= 1.28.1, < 2.0)
|
159
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
160
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
156
161
|
ruby-progressbar (~> 1.7)
|
157
|
-
unicode-display_width (>= 2.4.0, <
|
158
|
-
rubocop-ast (1.
|
159
|
-
parser (>= 3.
|
160
|
-
rubocop-capybara (2.
|
162
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
163
|
+
rubocop-ast (1.38.0)
|
164
|
+
parser (>= 3.3.1.0)
|
165
|
+
rubocop-capybara (2.21.0)
|
161
166
|
rubocop (~> 1.41)
|
162
|
-
rubocop-factory_bot (2.
|
163
|
-
rubocop (~> 1.
|
164
|
-
rubocop-performance (1.
|
165
|
-
rubocop (>= 1.
|
166
|
-
rubocop-ast (>=
|
167
|
-
rubocop-rspec (
|
168
|
-
rubocop (~> 1.
|
169
|
-
|
170
|
-
rubocop
|
167
|
+
rubocop-factory_bot (2.26.1)
|
168
|
+
rubocop (~> 1.61)
|
169
|
+
rubocop-performance (1.23.1)
|
170
|
+
rubocop (>= 1.48.1, < 2.0)
|
171
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
172
|
+
rubocop-rspec (3.4.0)
|
173
|
+
rubocop (~> 1.61)
|
174
|
+
rubocop-rspec_rails (2.30.0)
|
175
|
+
rubocop (~> 1.61)
|
176
|
+
rubocop-rspec (~> 3, >= 3.0.1)
|
171
177
|
ruby-progressbar (1.13.0)
|
172
|
-
|
178
|
+
securerandom (0.4.1)
|
173
179
|
simplecov (0.22.0)
|
174
180
|
docile (~> 1.1)
|
175
181
|
simplecov-html (~> 0.11)
|
176
182
|
simplecov_json_formatter (~> 0.1)
|
177
|
-
simplecov-html (0.
|
183
|
+
simplecov-html (0.13.1)
|
178
184
|
simplecov_json_formatter (0.1.4)
|
179
185
|
snaky_hash (2.0.1)
|
180
186
|
hashie
|
181
187
|
version_gem (~> 1.1, >= 1.1.1)
|
182
|
-
|
183
|
-
language_server-protocol (~> 3.17.0.2)
|
184
|
-
lint_roller (~> 1.0)
|
185
|
-
rubocop (~> 1.57.2)
|
186
|
-
standard-custom (~> 1.0.0)
|
187
|
-
standard-performance (~> 1.2)
|
188
|
-
standard-custom (1.0.2)
|
189
|
-
lint_roller (~> 1.0)
|
190
|
-
rubocop (~> 1.50)
|
191
|
-
standard-performance (1.2.1)
|
192
|
-
lint_roller (~> 1.1)
|
193
|
-
rubocop-performance (~> 1.19.1)
|
194
|
-
super_diff (0.10.0)
|
188
|
+
super_diff (0.15.0)
|
195
189
|
attr_extras (>= 6.2.4)
|
196
190
|
diff-lcs
|
197
191
|
patience_diff
|
198
|
-
thor (1.3.
|
192
|
+
thor (1.3.2)
|
199
193
|
tzinfo (2.0.6)
|
200
194
|
concurrent-ruby (~> 1.0)
|
201
|
-
unicode-display_width (
|
202
|
-
|
203
|
-
|
204
|
-
|
195
|
+
unicode-display_width (3.1.4)
|
196
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
197
|
+
unicode-emoji (4.0.4)
|
198
|
+
uri (1.0.2)
|
199
|
+
vcr (6.3.1)
|
200
|
+
base64
|
201
|
+
version_gem (1.1.4)
|
202
|
+
webmock (3.25.0)
|
205
203
|
addressable (>= 2.8.0)
|
206
204
|
crack (>= 0.3.2)
|
207
205
|
hashdiff (>= 0.4.0, < 2.0.0)
|
208
|
-
zeitwerk (2.
|
206
|
+
zeitwerk (2.7.1)
|
209
207
|
|
210
208
|
PLATFORMS
|
209
|
+
arm64-darwin-24
|
211
210
|
x86_64-darwin-19
|
212
211
|
x86_64-darwin-22
|
213
212
|
x86_64-linux
|
@@ -216,12 +215,16 @@ DEPENDENCIES
|
|
216
215
|
byebug
|
217
216
|
rake (~> 13.0)
|
218
217
|
rspec (~> 3.0)
|
218
|
+
rubocop
|
219
|
+
rubocop-capybara
|
220
|
+
rubocop-factory_bot
|
221
|
+
rubocop-performance
|
219
222
|
rubocop-rspec
|
223
|
+
rubocop-rspec_rails
|
220
224
|
simplecov
|
221
|
-
standard
|
222
225
|
sul_orcid_client!
|
223
226
|
vcr
|
224
227
|
webmock
|
225
228
|
|
226
229
|
BUNDLED WITH
|
227
|
-
2.
|
230
|
+
2.5.14
|
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
[](https://badge.fury.io/rb/sul_orcid_client)
|
2
2
|
[](https://dl.circleci.com/status-badge/redirect/gh/sul-dlss/orcid_client/tree/main)
|
3
|
-
[](https://codeclimate.com/github/sul-dlss/orcid_client/test_coverage)
|
3
|
+
[](https://codecov.io/github/sul-dlss/orcid_client)
|
5
4
|
|
6
5
|
# orcid_client
|
7
6
|
API client for accessing ORCID API and for mapping to ORCID works.
|
data/Rakefile
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'rubocop/rake_task'
|
6
6
|
|
7
7
|
RSpec::Core::RakeTask.new(:spec)
|
8
8
|
RuboCop::RakeTask.new
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class SulOrcidClient
|
2
4
|
# Helper methods for working with Orcid in Cocina
|
3
5
|
# NOTE: there is similar code in dor_indexing_app which fetches
|
@@ -8,31 +10,33 @@ class SulOrcidClient
|
|
8
10
|
# @param [Cocina::Models::Contributor] contributor to check
|
9
11
|
# @return [Boolean] true unless the contributor has a citation status of false
|
10
12
|
def self.cited?(contributor)
|
11
|
-
contributor.note.none? { |note| note.type ==
|
13
|
+
contributor.note.none? { |note| note.type == 'citation status' && note.value == 'false' }
|
12
14
|
end
|
13
15
|
|
14
16
|
# @param [Cocina::Models::Contributor] contributor to check
|
15
17
|
# @return [String, nil] orcid id including host if present
|
18
|
+
# rubocop:disable Metrics/AbcSize
|
16
19
|
def self.orcidid(contributor)
|
17
|
-
identifier = contributor.identifier.find { |
|
20
|
+
identifier = contributor.identifier.find { |check_identifier| check_identifier.type == 'ORCID' }
|
18
21
|
return unless identifier
|
19
22
|
|
20
23
|
# some records have the full ORCID URI in the data, just return it if so, e.g. druid:gf852zt8324
|
21
24
|
return identifier.uri if identifier.uri
|
22
|
-
return identifier.value if identifier.value.start_with?(
|
25
|
+
return identifier.value if identifier.value.start_with?('https://orcid.org/')
|
23
26
|
|
24
27
|
# some records have just the ORCIDID without the URL prefix, add it if so, e.g. druid:tp865ng1792
|
25
|
-
return URI.join(
|
28
|
+
return URI.join('https://orcid.org/', identifier.value).to_s if identifier.source.uri.blank?
|
26
29
|
|
27
30
|
URI.join(identifier.source.uri, identifier.value).to_s
|
28
31
|
end
|
32
|
+
# rubocop:enable Metrics/AbcSize
|
29
33
|
|
30
34
|
# @param [Cocina::Models::Description] description containing contributors to check
|
31
35
|
# @return [Array<String>] orcid ids including host if present
|
32
36
|
# Note that non-cited contributors are excluded.
|
33
37
|
def self.cited_orcidids(description)
|
34
38
|
cited_contributors = description.contributor.select { |contributor| cited?(contributor) }
|
35
|
-
cited_contributors.
|
39
|
+
cited_contributors.filter_map { |contributor| orcidid(contributor) }
|
36
40
|
end
|
37
41
|
end
|
38
42
|
end
|
@@ -1,9 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class SulOrcidClient
|
2
4
|
# Maps a Cocina Contributor to an Orcid Contributor.
|
3
|
-
|
4
5
|
class ContributorMapper
|
5
6
|
def self.map(contributor:)
|
6
|
-
new(contributor:
|
7
|
+
new(contributor:).map
|
7
8
|
end
|
8
9
|
|
9
10
|
# @param [Cocina::Models::Contributor] contributor to map
|
@@ -15,9 +16,9 @@ class SulOrcidClient
|
|
15
16
|
return unless CocinaSupport.cited?(contributor)
|
16
17
|
|
17
18
|
{
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
'credit-name': map_credit_name,
|
20
|
+
'contributor-orcid': map_orcid,
|
21
|
+
'contributor-attributes': map_attributes
|
21
22
|
}.compact
|
22
23
|
end
|
23
24
|
|
@@ -27,54 +28,56 @@ class SulOrcidClient
|
|
27
28
|
|
28
29
|
def map_credit_name
|
29
30
|
value = if contributor.name.first&.structuredValue.present?
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
name_from_structured_value(contributor.name.first.structuredValue)
|
32
|
+
else
|
33
|
+
contributor.name.first&.value
|
34
|
+
end
|
34
35
|
|
35
36
|
return unless value
|
36
37
|
|
37
38
|
{
|
38
|
-
value:
|
39
|
+
value:
|
39
40
|
}
|
40
41
|
end
|
41
42
|
|
42
43
|
def name_from_structured_value(structured_value)
|
43
|
-
forename = structured_value.find { |name_part| name_part.type ==
|
44
|
-
surname = structured_value.find { |name_part| name_part.type ==
|
45
|
-
[forename, surname].join(
|
44
|
+
forename = structured_value.find { |name_part| name_part.type == 'forename' }&.value
|
45
|
+
surname = structured_value.find { |name_part| name_part.type == 'surname' }&.value
|
46
|
+
[forename, surname].join(' ')
|
46
47
|
end
|
47
48
|
|
49
|
+
IDENTIFIER_TYPES = %w[ORCID ROR].freeze
|
50
|
+
|
48
51
|
def map_orcid
|
49
|
-
identifier = contributor.identifier.find { |
|
52
|
+
identifier = contributor.identifier.find { |check_identifier| IDENTIFIER_TYPES.include?(check_identifier.type) }
|
50
53
|
|
51
54
|
return unless identifier
|
52
55
|
|
53
56
|
{
|
54
57
|
uri: URI.join(identifier.source.uri, identifier.value).to_s,
|
55
58
|
path: identifier.value,
|
56
|
-
host:
|
59
|
+
host: identifier.type == 'ORCID' ? 'orcid.org' : 'ror.org'
|
57
60
|
}
|
58
61
|
end
|
59
62
|
|
60
63
|
def map_attributes
|
61
64
|
{
|
62
|
-
|
65
|
+
'contributor-role': map_role
|
63
66
|
}.compact.presence
|
64
67
|
end
|
65
68
|
|
66
69
|
MARC_RELATOR_MAP = {
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
}
|
70
|
+
'aut' => 'author',
|
71
|
+
'cmp' => 'author',
|
72
|
+
'ctb' => 'author',
|
73
|
+
'cre' => 'author',
|
74
|
+
'edt' => 'editor',
|
75
|
+
'rth' => 'principal-investigator'
|
76
|
+
}.freeze
|
74
77
|
|
75
78
|
def map_role
|
76
|
-
role = contributor.role.find do |
|
77
|
-
|
79
|
+
role = contributor.role.find do |check_role|
|
80
|
+
check_role.source&.code == 'marcrelator' && MARC_RELATOR_MAP.key?(check_role.code)
|
78
81
|
end
|
79
82
|
|
80
83
|
return unless role
|