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.
- checksums.yaml +4 -4
- data/Gemfile.lock +37 -36
- data/commonmeta.gemspec +1 -1
- data/lib/commonmeta/metadata_utils.rb +2 -0
- data/lib/commonmeta/readers/json_post_reader.rb +78 -0
- data/lib/commonmeta/utils.rb +19 -0
- data/lib/commonmeta/version.rb +1 -1
- data/spec/author_utils_spec.rb +10 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_item_metadata/blogger_post.yml +94 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_item_metadata/ghost_post.yml +117 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_item_metadata/ghost_post_with_doi.yml +117 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_item_metadata/jekyll_post.yml +170 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_item_metadata/wordpress_post.yml +163 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_post_metadata/blogger_post.yml +94 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_post_metadata/ghost_post_with_doi.yml +117 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_post_metadata/jekyll_post.yml +87 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_post_metadata/wordpress_post.yml +163 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_link/license.yml +221 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_link/url.yml +221 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/json_item_from_rogue_scholar_with_doi.yml +163 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/json_item_from_upstream_blog.yml +243 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/json_post_from_rogue_scholar_with_doi.yml +163 -0
- data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/json_post_from_upstream_blog.yml +243 -0
- data/spec/readers/json_post_reader_spec.rb +89 -0
- data/spec/utils_spec.rb +330 -314
- data/spec/writers/crossref_xml_writer_spec.rb +183 -137
- metadata +22 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ff3685620f0d6399524eac22d162f7b32391fa1424783a30e6c2f914d30deea
|
4
|
+
data.tar.gz: bf986a52084af3c28fb163a59022b1ede266b37b77bfd0bf8365c35fd98893b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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.
|
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.
|
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.
|
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.
|
87
|
+
i18n (1.14.0)
|
90
88
|
concurrent-ruby (~> 1.0)
|
91
89
|
json (2.6.3)
|
92
|
-
json-canonicalization (0.3.
|
93
|
-
json-ld (3.2.
|
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 (
|
99
|
-
rdf (~> 3.2, >= 3.2.
|
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.
|
104
|
-
ecma-re-validator (~> 0.3)
|
101
|
+
json_schemer (1.0.1)
|
105
102
|
hana (~> 1.3)
|
106
103
|
regexp_parser (~> 2.0)
|
107
|
-
|
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.
|
113
|
+
loofah (2.21.3)
|
117
114
|
crass (~> 1.0.2)
|
118
|
-
nokogiri (>= 1.
|
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.
|
120
|
+
nokogiri (1.15.2-arm64-darwin)
|
124
121
|
racc (~> 1.4)
|
125
|
-
oj (3.
|
122
|
+
oj (3.15.0)
|
126
123
|
optimist (3.0.1)
|
127
|
-
parallel (1.
|
128
|
-
parser (3.2.2.
|
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 (
|
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.
|
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.
|
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.
|
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.
|
169
|
+
rspec-core (3.12.2)
|
173
170
|
rspec-support (~> 3.12.0)
|
174
|
-
rspec-expectations (3.12.
|
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.
|
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.
|
191
|
+
rubocop-ast (1.29.0)
|
195
192
|
parser (>= 3.2.1.0)
|
196
|
-
rubocop-capybara (2.
|
193
|
+
rubocop-capybara (2.18.0)
|
197
194
|
rubocop (~> 1.41)
|
198
|
-
rubocop-
|
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.
|
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
|
-
|
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.
|
218
|
-
thor (1.2.
|
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.
|
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
|
data/lib/commonmeta/utils.rb
CHANGED
@@ -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?
|
data/lib/commonmeta/version.rb
CHANGED
data/spec/author_utils_spec.rb
CHANGED
@@ -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=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDUzfHxjb250YWluZXJ8ZW58MHx8fHwxNjg0MjMyMTQ0fDA&ixlib=rb-4.0.3&q=80&w=2000","content_html":"
|
52
|
+
<p><img src=\"https://images.unsplash.com/photo-1523351964962-1ee5847816c3?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDUzfHxjb250YWluZXJ8ZW58MHx8fHwxNjg0MjMyMTQ0fDA&ixlib=rb-4.0.3&q=80&w=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
|