commonmeta-ruby 3.0.10 → 3.2.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.
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