commonmeta-ruby 3.0.10 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +37 -36
  3. data/commonmeta.gemspec +1 -1
  4. data/lib/commonmeta/metadata_utils.rb +2 -0
  5. data/lib/commonmeta/readers/json_post_reader.rb +78 -0
  6. data/lib/commonmeta/utils.rb +19 -0
  7. data/lib/commonmeta/version.rb +1 -1
  8. data/spec/author_utils_spec.rb +10 -0
  9. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_item_metadata/blogger_post.yml +94 -0
  10. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_item_metadata/ghost_post.yml +117 -0
  11. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_item_metadata/ghost_post_with_doi.yml +117 -0
  12. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_item_metadata/jekyll_post.yml +170 -0
  13. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_item_metadata/wordpress_post.yml +163 -0
  14. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_post_metadata/blogger_post.yml +94 -0
  15. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_post_metadata/ghost_post_with_doi.yml +117 -0
  16. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_post_metadata/jekyll_post.yml +87 -0
  17. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_post_metadata/wordpress_post.yml +163 -0
  18. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_link/license.yml +221 -0
  19. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_link/url.yml +221 -0
  20. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/json_item_from_rogue_scholar_with_doi.yml +163 -0
  21. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/json_item_from_upstream_blog.yml +243 -0
  22. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/json_post_from_rogue_scholar_with_doi.yml +163 -0
  23. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/json_post_from_upstream_blog.yml +243 -0
  24. data/spec/readers/json_post_reader_spec.rb +89 -0
  25. data/spec/utils_spec.rb +330 -314
  26. data/spec/writers/crossref_xml_writer_spec.rb +183 -137
  27. metadata +22 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dbd0cff9167f3cf4cbef16d1b2f344dfbaaaa0c5f121f385f8e2703fedd42b0d
4
- data.tar.gz: 601f92cc97809057378e7dd89e36d1918a18280201b25a25ad8a13ecd1412a04
3
+ metadata.gz: 1ff3685620f0d6399524eac22d162f7b32391fa1424783a30e6c2f914d30deea
4
+ data.tar.gz: bf986a52084af3c28fb163a59022b1ede266b37b77bfd0bf8365c35fd98893b3
5
5
  SHA512:
6
- metadata.gz: d0e2953f19c0364ad7f774fe38be92bf9df6b975c02568e980ac4cfb7a0fae590aeda39df9d3c80332701db4cc7bfd81648c987b1e96eed6cd1595baf758376d
7
- data.tar.gz: 76b133fe3e101ba09c62c362d41035fd323e262575338866bacdbd2e07544b4b1e63583c304c827f9c386c22c7ea45c7f2b0c6eb304cf060b10f8e32e77e3796
6
+ metadata.gz: 447cc3b60622046224caf62ee2afa70f35f1b47c229c7407f126a3efcc6815cf129386590c6f1114c894111b657326fc35b442427c84907058bd809236a5afff
7
+ data.tar.gz: 69715e0926e03fc2441b8236a6e6beb0440b69dad8bde707f8d097a3d1922b71b3c80ac4c6286d8fc1fa5d489cc29be02250be6c4a6aadd0747d91bef1251b78
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- commonmeta-ruby (3.0.10)
4
+ commonmeta-ruby (3.2.0)
5
5
  activesupport (>= 4.2.5, < 8.0)
6
6
  addressable (~> 2.8.1, < 2.8.2)
7
7
  base32-url (>= 0.5.0, < 1)
@@ -13,7 +13,7 @@ PATH
13
13
  gender_detector (~> 2.0)
14
14
  http (~> 5.1, >= 5.1.1)
15
15
  json-ld-preloaded (~> 3.2, >= 3.2.2)
16
- json_schemer (~> 0.2.23)
16
+ json_schemer (~> 1.0.1)
17
17
  jsonlint (~> 0.3.0)
18
18
  loofah (~> 2.19)
19
19
  namae (~> 1.0)
@@ -25,7 +25,7 @@ PATH
25
25
  GEM
26
26
  remote: https://rubygems.org/
27
27
  specs:
28
- activesupport (7.0.4.3)
28
+ activesupport (7.0.5)
29
29
  concurrent-ruby (~> 1.0, >= 1.0.2)
30
30
  i18n (>= 1.6, < 2)
31
31
  minitest (>= 5.1)
@@ -57,14 +57,12 @@ GEM
57
57
  docile (1.4.0)
58
58
  domain_name (0.5.20190701)
59
59
  unf (>= 0.0.5, < 1.0.0)
60
- ebnf (2.3.2)
60
+ ebnf (2.3.3)
61
61
  htmlentities (~> 4.3)
62
62
  rdf (~> 3.2)
63
63
  scanf (~> 1.0)
64
64
  sxp (~> 1.2)
65
65
  unicode-types (~> 1.8)
66
- ecma-re-validator (0.4.0)
67
- regexp_parser (~> 2.2)
68
66
  edtf (3.1.1)
69
67
  activesupport (>= 3.0, < 8.0)
70
68
  ffi (1.15.5)
@@ -86,25 +84,24 @@ GEM
86
84
  http-cookie (1.0.5)
87
85
  domain_name (~> 0.5)
88
86
  http-form_data (2.3.0)
89
- i18n (1.12.0)
87
+ i18n (1.14.0)
90
88
  concurrent-ruby (~> 1.0)
91
89
  json (2.6.3)
92
- json-canonicalization (0.3.1)
93
- json-ld (3.2.3)
90
+ json-canonicalization (0.3.2)
91
+ json-ld (3.2.5)
94
92
  htmlentities (~> 4.3)
95
- json-canonicalization (~> 0.3)
93
+ json-canonicalization (~> 0.3, >= 0.3.2)
96
94
  link_header (~> 0.0, >= 0.0.8)
97
95
  multi_json (~> 1.15)
98
- rack (~> 2.2)
99
- rdf (~> 3.2, >= 3.2.9)
96
+ rack (>= 2.2, < 4)
97
+ rdf (~> 3.2, >= 3.2.10)
100
98
  json-ld-preloaded (3.2.2)
101
99
  json-ld (~> 3.2)
102
100
  rdf (~> 3.2)
103
- json_schemer (0.2.24)
104
- ecma-re-validator (~> 0.3)
101
+ json_schemer (1.0.1)
105
102
  hana (~> 1.3)
106
103
  regexp_parser (~> 2.0)
107
- uri_template (~> 0.7)
104
+ simpleidn (~> 0.2)
108
105
  jsonlint (0.3.0)
109
106
  oj (~> 3)
110
107
  optimist (~> 3)
@@ -113,19 +110,19 @@ GEM
113
110
  llhttp-ffi (0.4.0)
114
111
  ffi-compiler (~> 1.0)
115
112
  rake (~> 13.0)
116
- loofah (2.20.0)
113
+ loofah (2.21.3)
117
114
  crass (~> 1.0.2)
118
- nokogiri (>= 1.5.9)
115
+ nokogiri (>= 1.12.0)
119
116
  matrix (0.4.2)
120
117
  minitest (5.18.0)
121
118
  multi_json (1.15.0)
122
119
  namae (1.1.1)
123
- nokogiri (1.14.3-arm64-darwin)
120
+ nokogiri (1.15.2-arm64-darwin)
124
121
  racc (~> 1.4)
125
- oj (3.14.3)
122
+ oj (3.15.0)
126
123
  optimist (3.0.1)
127
- parallel (1.22.1)
128
- parser (3.2.2.0)
124
+ parallel (1.23.0)
125
+ parser (3.2.2.1)
129
126
  ast (~> 2.4.1)
130
127
  postrank-uri (1.1)
131
128
  addressable (>= 2.4.0)
@@ -133,12 +130,12 @@ GEM
133
130
  public_suffix (>= 4.0.0, < 5)
134
131
  public_suffix (4.0.7)
135
132
  racc (1.6.2)
136
- rack (2.2.6.4)
133
+ rack (3.0.7)
137
134
  rack-test (2.1.0)
138
135
  rack (>= 1.3)
139
136
  rainbow (3.1.1)
140
137
  rake (13.0.6)
141
- rdf (3.2.9)
138
+ rdf (3.2.10)
142
139
  link_header (~> 0.0, >= 0.0.8)
143
140
  rdf-aggregate-repo (3.2.1)
144
141
  rdf (~> 3.2)
@@ -158,20 +155,20 @@ GEM
158
155
  rdf-turtle (3.2.1)
159
156
  ebnf (~> 2.3)
160
157
  rdf (~> 3.2)
161
- rdf-vocab (3.2.5)
158
+ rdf-vocab (3.2.6)
162
159
  rdf (~> 3.2, >= 3.2.4)
163
160
  rdf-xsd (3.2.1)
164
161
  rdf (~> 3.2)
165
162
  rexml (~> 3.2)
166
- regexp_parser (2.7.0)
163
+ regexp_parser (2.8.0)
167
164
  rexml (3.2.5)
168
165
  rspec (3.12.0)
169
166
  rspec-core (~> 3.12.0)
170
167
  rspec-expectations (~> 3.12.0)
171
168
  rspec-mocks (~> 3.12.0)
172
- rspec-core (3.12.1)
169
+ rspec-core (3.12.2)
173
170
  rspec-support (~> 3.12.0)
174
- rspec-expectations (3.12.2)
171
+ rspec-expectations (3.12.3)
175
172
  diff-lcs (>= 1.2.0, < 2.0)
176
173
  rspec-support (~> 3.12.0)
177
174
  rspec-mocks (3.12.5)
@@ -181,7 +178,7 @@ GEM
181
178
  rspec-xsd (0.1.0)
182
179
  nokogiri (~> 1.6)
183
180
  rspec (~> 3)
184
- rubocop (1.50.1)
181
+ rubocop (1.52.0)
185
182
  json (~> 2.3)
186
183
  parallel (~> 1.10)
187
184
  parser (>= 3.2.0.0)
@@ -191,18 +188,21 @@ GEM
191
188
  rubocop-ast (>= 1.28.0, < 2.0)
192
189
  ruby-progressbar (~> 1.7)
193
190
  unicode-display_width (>= 2.4.0, < 3.0)
194
- rubocop-ast (1.28.0)
191
+ rubocop-ast (1.29.0)
195
192
  parser (>= 3.2.1.0)
196
- rubocop-capybara (2.17.1)
193
+ rubocop-capybara (2.18.0)
197
194
  rubocop (~> 1.41)
198
- rubocop-performance (1.17.1)
195
+ rubocop-factory_bot (2.23.1)
196
+ rubocop (~> 1.33)
197
+ rubocop-performance (1.18.0)
199
198
  rubocop (>= 1.7.0, < 2.0)
200
199
  rubocop-ast (>= 0.4.0)
201
200
  rubocop-rake (0.6.0)
202
201
  rubocop (~> 1.0)
203
- rubocop-rspec (2.19.0)
202
+ rubocop-rspec (2.22.0)
204
203
  rubocop (~> 1.33)
205
204
  rubocop-capybara (~> 2.17)
205
+ rubocop-factory_bot (~> 2.22)
206
206
  ruby-progressbar (1.13.0)
207
207
  scanf (1.0.0)
208
208
  simplecov (0.22.0)
@@ -211,11 +211,13 @@ GEM
211
211
  simplecov_json_formatter (~> 0.1)
212
212
  simplecov-html (0.12.3)
213
213
  simplecov_json_formatter (0.1.4)
214
- sxp (1.2.3)
214
+ simpleidn (0.2.1)
215
+ unf (~> 0.1.4)
216
+ sxp (1.2.4)
215
217
  matrix (~> 0.4)
216
218
  rdf (~> 3.2)
217
- temple (0.10.0)
218
- thor (1.2.1)
219
+ temple (0.10.2)
220
+ thor (1.2.2)
219
221
  tilt (2.1.0)
220
222
  tzinfo (2.0.6)
221
223
  concurrent-ruby (~> 1.0)
@@ -224,7 +226,6 @@ GEM
224
226
  unf_ext (0.0.8.2)
225
227
  unicode-display_width (2.4.2)
226
228
  unicode-types (1.8.0)
227
- uri_template (0.7.0)
228
229
  vcr (6.1.0)
229
230
  webmock (3.18.1)
230
231
  addressable (>= 2.8.0)
data/commonmeta.gemspec CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
30
30
  s.add_dependency 'http', '~> 5.1', '>= 5.1.1'
31
31
  s.add_dependency 'json-ld-preloaded', '~> 3.2', '>= 3.2.2'
32
32
  s.add_dependency 'jsonlint', '~> 0.3.0'
33
- s.add_dependency 'json_schemer', '~> 0.2.23'
33
+ s.add_dependency 'json_schemer', '~> 1.0.1'
34
34
  s.add_dependency 'loofah', '~> 2.19'
35
35
  s.add_dependency 'namae', '~> 1.0'
36
36
  s.add_dependency 'postrank-uri', '~> 1.1'
@@ -13,6 +13,7 @@ require_relative 'readers/codemeta_reader'
13
13
  require_relative 'readers/crossref_reader'
14
14
  require_relative 'readers/crossref_xml_reader'
15
15
  require_relative 'readers/datacite_reader'
16
+ require_relative 'readers/json_post_reader'
16
17
  require_relative 'readers/npm_reader'
17
18
  require_relative 'readers/ris_reader'
18
19
  require_relative 'readers/schema_org_reader'
@@ -46,6 +47,7 @@ module Commonmeta
46
47
  include Commonmeta::Readers::CrossrefXmlReader
47
48
  include Commonmeta::Readers::CslReader
48
49
  include Commonmeta::Readers::DataciteReader
50
+ include Commonmeta::Readers::JsonPostReader
49
51
  include Commonmeta::Readers::NpmReader
50
52
  include Commonmeta::Readers::RisReader
51
53
  include Commonmeta::Readers::SchemaOrgReader
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Commonmeta
4
+ module Readers
5
+ module JsonPostReader
6
+ def get_json_post(id: nil, **_options)
7
+ return { "string" => nil, "state" => "not_found" } unless id.present?
8
+
9
+ url = normalize_id(id)
10
+ response = HTTP.get(url)
11
+ return { "string" => nil, "state" => "not_found" } unless response.status.success?
12
+
13
+ { "string" => response.body.to_s }
14
+ end
15
+
16
+ def read_json_post(string: nil, **options)
17
+ read_options = ActiveSupport::HashWithIndifferentAccess.new(options.except(:doi, :id, :url,
18
+ :sandbox, :validate, :ra))
19
+
20
+ meta = string.present? ? JSON.parse(string) : {}
21
+
22
+ id = options[:doi] ? normalize_doi(options[:doi]) : normalize_id(meta.fetch("id", nil))
23
+ url = normalize_url(meta.fetch("url", nil))
24
+ type = "Article"
25
+ creators = if meta.fetch("authors", nil).present?
26
+ get_authors(from_json_post(Array.wrap(meta.fetch("authors"))))
27
+ else
28
+ [{ "type" => "Organization", "name" => ":(unav)" }]
29
+ end
30
+ titles = [{ "title" => meta.fetch("title", nil) }]
31
+ publisher = { "name" => meta.dig("blog", "title") }
32
+
33
+ date = {}
34
+ date["published"] = get_iso8601_date(meta.dig("date_published")) if meta.dig("date_published").present?
35
+ date["updated"] = get_iso8601_date(meta.dig("date_modified")) if meta.dig("date_modified").present?
36
+
37
+ license = if meta.dig("blog", "license").present?
38
+ hsh_to_spdx("rightsURI" => meta.dig("blog", "license"))
39
+ end
40
+ home_page_url = normalize_url(meta.dig("blog", "home_page_url"))
41
+ container = if meta.dig("blog", "title").present?
42
+ { "type" => "Periodical",
43
+ "title" => meta.dig("blog", "title"),
44
+ "identifier" => home_page_url,
45
+ "identifierType" => "URL" }
46
+ end
47
+
48
+ descriptions = if meta.fetch("summary", nil).present?
49
+ [{ "description" => sanitize(meta.fetch("summary", nil)),
50
+ "descriptionType" => "Abstract" }]
51
+ else
52
+ []
53
+ end
54
+ language = meta.fetch("language", nil) || meta.fetch("blog", "language", nil)
55
+ state = id.present? || read_options.present? ? "findable" : "not_found"
56
+ subjects = Array.wrap(meta.fetch("tags", nil)).reduce([]) do |sum, subject|
57
+ sum += name_to_fos(subject)
58
+
59
+ sum
60
+ end
61
+
62
+ { "id" => id,
63
+ "type" => type,
64
+ "url" => url,
65
+ "titles" => titles,
66
+ "creators" => creators,
67
+ "publisher" => publisher,
68
+ "container" => container,
69
+ "date" => date,
70
+ "language" => language,
71
+ "descriptions" => descriptions,
72
+ "license" => license,
73
+ "subjects" => subjects.presence,
74
+ "state" => state }.compact.merge(read_options)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -468,6 +468,8 @@ module Commonmeta
468
468
  "cff"
469
469
  elsif %r{\A(http|https):/(/)?github\.com/(.+)\z}.match?(id)
470
470
  "cff"
471
+ elsif %r{\A(http|https):/(/)?rogue-scholar\.org/api/posts/(.+)\z}.match?(id)
472
+ "json_post"
471
473
  else
472
474
  "schema_org"
473
475
  end
@@ -875,6 +877,12 @@ module Commonmeta
875
877
  }
876
878
  end
877
879
 
880
+ def from_json_post(element)
881
+ mapping = { "url" => "id" }
882
+
883
+ map_hash_keys(element: element, mapping: mapping)
884
+ end
885
+
878
886
  def from_csl(element)
879
887
  Array.wrap(element).map do |a|
880
888
  if a["literal"].present?
@@ -1068,6 +1076,8 @@ module Commonmeta
1068
1076
 
1069
1077
  return iso8601_time.split(".").first + "Z" if iso8601_time.to_s.include? "."
1070
1078
 
1079
+ return iso8601_time.split("+").first + "Z" if iso8601_time.to_s.include? "+"
1080
+
1071
1081
  iso8601_time
1072
1082
  end
1073
1083
 
@@ -1084,6 +1094,15 @@ module Commonmeta
1084
1094
  dd.fetch("date", nil)
1085
1095
  end
1086
1096
 
1097
+ def get_link(links, link_type)
1098
+ ll = Array.wrap(links).find { |d| d["rel"] == link_type } || {}
1099
+ ll.fetch("href", nil)
1100
+ end
1101
+
1102
+ def rogue_scholar_api_url(id, _options = {})
1103
+ "https://rogue-scholar.org/api/posts/#{id}"
1104
+ end
1105
+
1087
1106
  # convert commonmeta dates to DataCite format
1088
1107
  def get_dates_from_date(date)
1089
1108
  return nil if date.nil?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Commonmeta
4
- VERSION = '3.0.10'
4
+ VERSION = '3.2.0'
5
5
  end
@@ -40,6 +40,16 @@ describe Commonmeta::Metadata, vcr: true do
40
40
  expect(subject.is_personal_name?(name: author['name'])).to be true
41
41
  end
42
42
 
43
+ it 'has unknown given name' do
44
+ author = { 'name' => 'Rintze Zelle' }
45
+ expect(subject.is_personal_name?(name: author['name'])).to be false
46
+ end
47
+
48
+ it 'has middle initial' do
49
+ author = { 'name' => 'Martin H. Fenner' }
50
+ expect(subject.is_personal_name?(name: author['name'])).to be true
51
+ end
52
+
43
53
  it 'has no info' do
44
54
  author = { 'name' => 'M Fenner' }
45
55
  expect(subject.is_personal_name?(name: author['name'])).to be false
@@ -0,0 +1,94 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://rogue-scholar.org/api/posts/1jgo59el
6
+ body:
7
+ encoding: UTF-8
8
+ string: ''
9
+ headers:
10
+ Connection:
11
+ - close
12
+ Host:
13
+ - rogue-scholar.org
14
+ User-Agent:
15
+ - http.rb/5.1.1
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Age:
22
+ - '0'
23
+ Cache-Control:
24
+ - public, max-age=0, must-revalidate
25
+ Content-Length:
26
+ - '5576'
27
+ Content-Type:
28
+ - application/json; charset=utf-8
29
+ Date:
30
+ - Sat, 03 Jun 2023 20:04:27 GMT
31
+ Etag:
32
+ - '"r6tc4lxjtm4ak"'
33
+ Server:
34
+ - Vercel
35
+ Strict-Transport-Security:
36
+ - max-age=63072000
37
+ X-Matched-Path:
38
+ - "/api/posts/[slug]"
39
+ X-Vercel-Cache:
40
+ - MISS
41
+ X-Vercel-Id:
42
+ - fra1::iad1::z7sjr-1685822666479-acd9f9ad8646
43
+ Connection:
44
+ - close
45
+ body:
46
+ encoding: UTF-8
47
+ string: '{"id":"https://iphylo.blogspot.com/2023/05/ten-years-and-million-links.html","short_id":"1jgo59el","url":"https://iphylo.blogspot.com/2023/05/ten-years-and-million-links.html","title":"Ten
48
+ years and a million links","summary":"As trailed on a Twitter thread last
49
+ week I’ve been working on a manuscript describing the efforts to map taxonomic
50
+ names to their original descriptions in the taxonomic literature. Putting
51
+ together a...","date_published":"2023-05-31T17:26:00Z","date_modified":null,"authors":[{"url":null,"name":"Roderic
52
+ Page"}],"image":null,"content_html":"<p>As trailed on a Twitter thread last
53
+ week I’ve been working on a manuscript describing the efforts to map taxonomic
54
+ names to their original descriptions in the taxonomic literature.</p>\n<blockquote
55
+ class=\"twitter-tweet\"><p lang=\"en\" dir=\"ltr\">Putting together a manuscript
56
+ on linking taxonomic names to the primary literature, basically “um, what,
57
+ exactly, have you been doing all these years?”. TL;DR Across fungi, plants,
58
+ and animals approx 1.3 million names have been linked to a persistent identifier
59
+ for a publication.</p>— Roderic Page (@rdmpage) <a href=\"https://twitter.com/rdmpage/status/1661714128413573120?ref_src=twsrc%5Etfw\">May
60
+ 25, 2023</a></blockquote> \n<p>The preprint is on bioRxiv <a href=\"https://doi.org/10.1101/2023.05.29.542697\">doi:10.1101/2023.05.29.542697</a></p>\n<blockquote>\n<p>A
61
+ major gap in the biodiversity knowledge graph is a connection between taxonomic
62
+ names and the taxonomic literature. While both names and publications often
63
+ have persistent identifiers (PIDs), such as Life Science Identifiers (LSIDs)
64
+ or Digital Object Identifiers (DOIs), LSIDs for names are rarely linked to
65
+ DOIs for publications. This article describes efforts to make those connections
66
+ across three large taxonomic databases: Index Fungorum, International Plant
67
+ Names Index (IPNI), and the Index of Organism Names (ION). Over a million
68
+ names have been matched to DOIs or other persistent identifiers for taxonomic
69
+ publications. This represents approximately 36% of names for which publication
70
+ data is available. The mappings between LSIDs and publication PIDs are made
71
+ available through ChecklistBank. Applications of this mapping are discussed,
72
+ including a web app to locate the citation of a taxonomic name, and a knowledge
73
+ graph that uses data on researcher’s ORCID ids to connect taxonomic names
74
+ and publications to authors of those names.</p>\n</blockquote>\n<p>Much of
75
+ the work has been linking taxa to names, which still has huge gaps. There
76
+ are also interesting differences in coverage between plants, animals, and
77
+ fungi (see preprint for details).</p>\n\n<div class=\"separator\" style=\"clear:
78
+ both;\"><a href=\"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdWsSQhqi1DErXMIHm28g37-fiALNIsI5eQZmvoX_Fe03ZSwtKHbYt-LCsCCAUop0AGcwy_w7NpIjylVH1hNrM9oW-6j9e6tHASha49TTqFvDg2_tEx3r74RRFsjUo4M_Qat8NmKaZSChOt2hI3LsMjTVLrEVirEckU-9Ei7ug-7OHQlR4LA/s2276/animals-coverage.png\"
79
+ style=\"display: block; padding: 1em 0; text-align: center; \"><img alt=\"\"
80
+ border=\"0\" width=\"320\" data-original-height=\"2276\" data-original-width=\"2276\"
81
+ src=\"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdWsSQhqi1DErXMIHm28g37-fiALNIsI5eQZmvoX_Fe03ZSwtKHbYt-LCsCCAUop0AGcwy_w7NpIjylVH1hNrM9oW-6j9e6tHASha49TTqFvDg2_tEx3r74RRFsjUo4M_Qat8NmKaZSChOt2hI3LsMjTVLrEVirEckU-9Ei7ug-7OHQlR4LA/s320/animals-coverage.png\"/></a></div><div
82
+ class=\"separator\" style=\"clear: both;\"><a href=\"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdyxlVJ-oyMCNPmHtHWjSxdxMSJvgzdWRGRF6Ad4dk7ab7gGDpuKdKmS9XhROkopw361ylfsTd1ZkwkF6BN0JlWNnVLCKY1AfryCfWKHkgPQM7u-0SELW9j8RlQIflb6ibaV64gwW7oJrEvOGECvR51F8EW8cRg-1usW-GBM5ymObj7zlObQ/s2276/fungi-coverage.png\"
83
+ style=\"display: block; padding: 1em 0; text-align: center; \"><img alt=\"\"
84
+ border=\"0\" width=\"320\" data-original-height=\"2276\" data-original-width=\"2276\"
85
+ src=\"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdyxlVJ-oyMCNPmHtHWjSxdxMSJvgzdWRGRF6Ad4dk7ab7gGDpuKdKmS9XhROkopw361ylfsTd1ZkwkF6BN0JlWNnVLCKY1AfryCfWKHkgPQM7u-0SELW9j8RlQIflb6ibaV64gwW7oJrEvOGECvR51F8EW8cRg-1usW-GBM5ymObj7zlObQ/s320/fungi-coverage.png\"/></a></div><div
86
+ class=\"separator\" style=\"clear: both;\"><a href=\"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgf0YBuvNSXWAJTfQ1jk4XSocMzCYHP7t6IPUqhjQ3mftgM_850igWaD2copgNH6Xk6T62xBU641wvwOvXgCCDY3m2xC_gaILXO9RGx8H3Gpy5OOncsLb9smpT2LIgtYOExVBVdDRWqA0AZ8-mQjWL7dL5TiG7MqVu8spT8ACoGOPR_T36hRA/s2276/plants-coverage.png\"
87
+ style=\"display: block; padding: 1em 0; text-align: center; \"><img alt=\"\"
88
+ border=\"0\" width=\"320\" data-original-height=\"2276\" data-original-width=\"2276\"
89
+ src=\"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgf0YBuvNSXWAJTfQ1jk4XSocMzCYHP7t6IPUqhjQ3mftgM_850igWaD2copgNH6Xk6T62xBU641wvwOvXgCCDY3m2xC_gaILXO9RGx8H3Gpy5OOncsLb9smpT2LIgtYOExVBVdDRWqA0AZ8-mQjWL7dL5TiG7MqVu8spT8ACoGOPR_T36hRA/s320/plants-coverage.png\"/></a></div>\n\n\nThere
90
+ is also a simple app to demonstrate these links, see <a href=\"https://species-cite.herokuapp.com\">https://species-cite.herokuapp.com</a>.\n\n\n\n<blockquote>\n<p>Written
91
+ with <a href=\"https://stackedit.io/\">StackEdit</a>.</p>\n</blockquote>","tags":[],"language":"en","blog_id":"tyfqw20","blog":{"id":"tyfqw20","title":"iPhylo","language":"en","favicon":null,"feed_url":"https://iphylo.blogspot.com/feeds/posts/default?alt=rss","home_page_url":"https://iphylo.blogspot.com/","license":"https://creativecommons.org/licenses/by/4.0/legalcode","category":"Natural
92
+ Sciences"}}'
93
+ recorded_at: Sat, 03 Jun 2023 20:04:27 GMT
94
+ recorded_with: VCR 6.1.0
@@ -0,0 +1,117 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://rogue-scholar.org/api/posts/1jgo8yel
6
+ body:
7
+ encoding: UTF-8
8
+ string: ''
9
+ headers:
10
+ Connection:
11
+ - close
12
+ Host:
13
+ - rogue-scholar.org
14
+ User-Agent:
15
+ - http.rb/5.1.1
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Age:
22
+ - '0'
23
+ Cache-Control:
24
+ - public, max-age=0, must-revalidate
25
+ Content-Length:
26
+ - '6894'
27
+ Content-Type:
28
+ - application/json; charset=utf-8
29
+ Date:
30
+ - Sun, 04 Jun 2023 07:20:26 GMT
31
+ Etag:
32
+ - '"r1h98s95tn5bh"'
33
+ Server:
34
+ - Vercel
35
+ Strict-Transport-Security:
36
+ - max-age=63072000
37
+ X-Matched-Path:
38
+ - "/api/posts/[slug]"
39
+ X-Vercel-Cache:
40
+ - MISS
41
+ X-Vercel-Id:
42
+ - fra1::iad1::pkzgk-1685863226488-42890f58a873
43
+ Connection:
44
+ - close
45
+ body:
46
+ encoding: UTF-8
47
+ string: '{"id":"https://doi.org/10.53731/4nwxn-frt36","short_id":"1jgo8yel","url":"https://blog.front-matter.io/posts/does-it-compose/","title":"Does
48
+ it compose?","summary":"One question I have increasingly asked myself in the
49
+ past few years. Meaning Can I run this open source software using Docker containers
50
+ and a Docker Compose file?As the Docker project turned ten this...","date_published":"2023-05-16T11:36:56Z","date_modified":"2023-05-16T11:36:56Z","authors":[{"url":"https://orcid.org/0000-0003-1419-2405","name":"Martin
51
+ Fenner"}],"image":"https://images.unsplash.com/photo-1523351964962-1ee5847816c3?crop&#x3D;entropy&cs&#x3D;tinysrgb&fit&#x3D;max&fm&#x3D;jpg&ixid&#x3D;M3wxMTc3M3wwfDF8c2VhcmNofDUzfHxjb250YWluZXJ8ZW58MHx8fHwxNjg0MjMyMTQ0fDA&ixlib&#x3D;rb-4.0.3&q&#x3D;80&w&#x3D;2000","content_html":"
52
+ <p><img src=\"https://images.unsplash.com/photo-1523351964962-1ee5847816c3?crop&#x3D;entropy&cs&#x3D;tinysrgb&fit&#x3D;max&fm&#x3D;jpg&ixid&#x3D;M3wxMTc3M3wwfDF8c2VhcmNofDUzfHxjb250YWluZXJ8ZW58MHx8fHwxNjg0MjMyMTQ0fDA&ixlib&#x3D;rb-4.0.3&q&#x3D;80&w&#x3D;2000\"></p><p>One
53
+ question I have increasingly asked myself in the past few years. Meaning </p><blockquote>Can
54
+ I run this open source software  using Docker containers and a Docker Compose
55
+ file?</blockquote><p>As the Docker project <a href=\"https://snyk.io/blog/the-docker-project-turns-10/\">turned
56
+ ten this spring</a>, it has become standard practice to distribute open source
57
+ software via Docker images and to provide a <a href=\"https://docs.docker.com/compose/\">Docker
58
+ Compose</a> file to run the software together with other dependencies. The
59
+ <a href=\"https://github.com/docker/awesome-compose\">Awesome Compose</a>
60
+ project has collected many examples, and all you need is a <code>docker-compose.yml</code>file
61
+ and a recent installation of Docker, e.g. <a href=\"https://www.docker.com/products/docker-desktop/\">Docker
62
+ Desktop</a>. Be aware that Docker Compose has evolved over the years. It started
63
+ out as a dedicated Python application but was later integrated into the Docker
64
+ application (written in Go) as Compose V2.</p><p>Docker and Docker Compose
65
+ allow you to run pretty complex applications without first addressing a long
66
+ list of requirements (which might conflict with other software you have installed),
67
+ or needing a long and complex build step where many things can go wrong. For
68
+ example a self-hosted instance of Supabase (a hosted Postgres database with
69
+ additional features) that I installed last week following <a href=\"https://supabase.com/docs/guides/self-hosting/docker\">these
70
+ instructions</a>.</p><p>An important open source project that I am involved
71
+ in is <a href=\"https://inveniordm.docs.cern.ch/\">InvenioRDM</a>, the turn-key
72
+ research data management repository. InvenioRDM started in 2019, with a first
73
+ production-suitable version in August 2021, and the <a href=\"https://inveniosoftware.org/products/rdm/#status\">next
74
+ major goal </a>is to have the large and popular <a href=\"https://zenodo.org/\">Zenodo</a>
75
+ repository running on top of InvenioRDM. Zenodo <a href=\"https://blog.zenodo.org/2023/05/08/2023-05-08-10years/\">turned
76
+ ten last week</a>, a few weeks after Docker. Interestingly, my personal tenth
77
+ anniversary was last year in May as I became a full-time software developer
78
+ and left academic medicine as a medical doctor treating cancer patients in
79
+ <a href=\"https://doi.org/10.53731/r294649-6f79289-8cw2j\">May 2012</a>.</p><p>Unfortunately,
80
+ InvenioRDM \"doesn''t compose\" yet. It is very close, but there are no ready-made
81
+ Docker images to download, and the <a href=\"https://inveniordm.docs.cern.ch/install/\">installation
82
+ instructions</a> start with installing a Python command-line tool (invenio-cli).
83
+ So if you have 1-2 hours to play with InvenioRDM and get a first impression,
84
+ there is no official solution from the InvenioRDM project yet. For this reason,
85
+ I started the <a href=\"https://github.com/front-matter/docker-invenio-rdm\">docker-invenio-rdm</a>
86
+ repository on Github. It contains a Docker Compose file that uses pre-built
87
+ Docker images, and using that file with a <code>docker compose up</code>command
88
+ on your local computer should give you a running InvenioRDM within 15 minutes:</p><figure
89
+ class=\"kg-card kg-image-card\"><img src=\"https://blog.front-matter.io/content/images/2023/05/Bildschirmfoto-2023-05-11-um-10.37.55.png\"
90
+ class=\"kg-image\" alt loading=\"lazy\" width=\"2000\" height=\"1210\" srcset=\"https://blog.front-matter.io/content/images/size/w600/2023/05/Bildschirmfoto-2023-05-11-um-10.37.55.png
91
+ 600w, https://blog.front-matter.io/content/images/size/w1000/2023/05/Bildschirmfoto-2023-05-11-um-10.37.55.png
92
+ 1000w, https://blog.front-matter.io/content/images/size/w1600/2023/05/Bildschirmfoto-2023-05-11-um-10.37.55.png
93
+ 1600w, https://blog.front-matter.io/content/images/2023/05/Bildschirmfoto-2023-05-11-um-10.37.55.png
94
+ 2193w\" sizes=\"(min-width: 720px) 720px\"></figure><p>I started this recently
95
+ and obviously want to move forward in two directions:</p><ul><li>fine-tune
96
+ the initial configuration to provide a great initial experience with InvenioRDM,
97
+ e.g. making it easy to <a href=\"https://inveniordm.docs.cern.ch/develop/topics/theming/\">theme</a>
98
+ the InvenioRDM instance</li><li>make this an official part of the InvenioRDM
99
+ project, extending the <a href=\"https://github.com/inveniosoftware/docker-invenio\">docker-invenio</a>
100
+ GitHub repository that provides Docker base images for InvenioRDM and other
101
+ projects using the Invenio software.</li></ul><p>But of course, Docker Compose
102
+ is not the answer to all questions regarding running Docker-based infrastructure.
103
+ For production environments, most people shy away from using Docker Compose.
104
+ The reasons for that and the alternatives will be the topic of a future blog
105
+ post (spoiler: there is exciting news).</p><p>Docker Compose also needs more
106
+ work to be set up correctly for development environments. It is a common practice
107
+ and a workflow I used while working at DataCite (where we launched Docker-based
108
+ infrastructure in 2016), but for now, the easiest way to set up InvenioRDM
109
+ development environments is using the <a href=\"https://inveniordm.docs.cern.ch/install/\">invenio-cli
110
+ tool with a local development environment</a>.</p><p>Please reach out to me
111
+ with feedback on running Docker Compose for InvenioRDM (use the <a href=\"https://github.com/front-matter/docker-invenio-rdm/discussions\">discussions</a>
112
+ feature in the GitHub repo), or if you have questions about running InvenioRDM
113
+ in production.</p> ","tags":["News"],"language":"en","blog_id":"f0m0e38","blog":{"id":"f0m0e38","title":"Front
114
+ Matter","language":"en","favicon":"https://blog.front-matter.io/favicon.png","feed_url":"https://blog.front-matter.io/atom/","home_page_url":"https://blog.front-matter.io/","license":"https://creativecommons.org/licenses/by/4.0/legalcode","category":"Engineering
115
+ and Technology"}}'
116
+ recorded_at: Sun, 04 Jun 2023 07:20:26 GMT
117
+ recorded_with: VCR 6.1.0