commonmeta-ruby 3.3.17 → 3.4.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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +37 -50
  3. data/bin/commonmeta +1 -1
  4. data/lib/commonmeta/cli.rb +7 -0
  5. data/lib/commonmeta/crossref_utils.rb +20 -0
  6. data/lib/commonmeta/readers/json_feed_reader.rb +19 -1
  7. data/lib/commonmeta/schema_utils.rb +1 -1
  8. data/lib/commonmeta/utils.rb +6 -4
  9. data/lib/commonmeta/version.rb +1 -1
  10. data/resources/{commonmeta_v0.9.2.json → commonmeta_v0.9.3.json} +32 -2
  11. data/spec/cli_spec.rb +1 -1
  12. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/blog_post_with_non-url_id.yml +84 -18
  13. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/blogger_post.yml +42 -14
  14. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/ghost_post_with_author_name_suffix.yml +184 -55
  15. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/ghost_post_with_doi.yml +76 -15
  16. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/ghost_post_with_institutional_author.yml +33 -12
  17. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/ghost_post_with_organizational_author.yml +44 -11
  18. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/ghost_post_with_related_identifiers.yml +366 -0
  19. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/ghost_post_without_doi.yml +144 -11
  20. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/jekyll_post.yml +42 -13
  21. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/jekyll_post_with_anonymous_author.yml +17 -13
  22. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/substack_post_with_broken_reference.yml +557 -262
  23. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/syldavia_gazette_post_with_references.yml +76 -47
  24. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/upstream_post_with_references.yml +303 -123
  25. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/wordpress_post.yml +108 -12
  26. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/wordpress_post_with_many_references.yml +3048 -441
  27. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/wordpress_post_with_references.yml +178 -31
  28. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/wordpress_post_with_tracking_code_on_url.yml +139 -17
  29. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/another_schema_org_from_front-matter.yml +47 -48
  30. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/journal_article.yml +5 -5
  31. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/journal_article_from_datacite.yml +7 -7
  32. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/json_feed_item_from_rogue_scholar_with_anonymous_author.yml +17 -13
  33. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/json_feed_item_from_rogue_scholar_with_doi.yml +108 -12
  34. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/json_feed_item_from_rogue_scholar_with_organizational_author.yml +44 -11
  35. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/json_feed_item_from_rogue_scholar_with_relations.yml +366 -0
  36. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/json_feed_item_from_upstream_blog.yml +200 -11
  37. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/json_feed_item_with_references.yml +303 -123
  38. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/posted_content.yml +16 -16
  39. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/schema_org_from_another_science_blog.yml +17 -17
  40. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/schema_org_from_front_matter.yml +111 -113
  41. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/schema_org_from_upstream_blog.yml +64 -57
  42. data/spec/readers/json_feed_reader_spec.rb +85 -57
  43. data/spec/writers/crossref_xml_writer_spec.rb +76 -40
  44. metadata +6 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d9089eaa55c76c89411f0b252418860d40c498b77ad5e07ff6937d26364fff4
4
- data.tar.gz: b251346f6fd8fe1714632587ee46196b00c3c4bb8c4ba7bf0fe6decd54c5a9e3
3
+ metadata.gz: 75ab77371ac7823493a9e182a81284ae858bc10ee4d2a1df6dd598518024d645
4
+ data.tar.gz: 696bccaa9835c5b5f7eefc666051fae1d01b608a4e94286b54630053324779b3
5
5
  SHA512:
6
- metadata.gz: 87733ee7cf23b71317df6c8ef7ad2eea099db43a6291a948f93b18220aeff5f3cf72e8ec9a9b0e36b3f243fe7b651d1b7d401341d0cf0524d0a6c3ea0db1bc7f
7
- data.tar.gz: 131dbb14b63cca5c62acce085746f0dc13ef99252bd9243a84c0565a5e671e45c613cc12903df297e4c9df8bd0f5a6d69b645d18e622dd895c0d120e0d7b7f46
6
+ metadata.gz: 6f21095312741ed18d18285ca29c836e1dc528dad317ce501beed5413407ce5d4436660298d9b593eda126e6814b45e0154bd10ec7c8f6e2c4f61794c7e097e7
7
+ data.tar.gz: 7887477aee2ae90f7a8c271be662ae35bf72c82b69df4afcf41e74ded776c8a96bfbc5af4d04839400cdf57151467b69451e5c5d740ea487b194f2b00bb42984
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- commonmeta-ruby (3.3.17)
4
+ commonmeta-ruby (3.4.0)
5
5
  activesupport (>= 4.2.5, < 8.0)
6
6
  addressable (~> 2.8.1, < 2.8.2)
7
7
  base32-url (>= 0.7.0, < 1)
@@ -27,7 +27,7 @@ PATH
27
27
  GEM
28
28
  remote: https://rubygems.org/
29
29
  specs:
30
- activesupport (7.0.6)
30
+ activesupport (7.0.7.2)
31
31
  concurrent-ruby (~> 1.0, >= 1.0.2)
32
32
  i18n (>= 1.6, < 2)
33
33
  minitest (>= 5.1)
@@ -37,6 +37,8 @@ GEM
37
37
  ast (2.4.2)
38
38
  base32-url (0.7.0)
39
39
  uuidtools (~> 2.1, >= 2.1.5)
40
+ base64 (0.1.1)
41
+ bcp47_spec (0.2.1)
40
42
  bibtex-ruby (6.0.0)
41
43
  latex-decode (~> 0.0)
42
44
  builder (3.2.4)
@@ -60,11 +62,11 @@ GEM
60
62
  docile (1.4.0)
61
63
  domain_name (0.5.20190701)
62
64
  unf (>= 0.0.5, < 1.0.0)
63
- ebnf (2.3.4)
65
+ ebnf (2.4.0)
64
66
  htmlentities (~> 4.3)
65
- rdf (~> 3.2)
67
+ rdf (~> 3.3)
66
68
  scanf (~> 1.0)
67
- sxp (~> 1.2)
69
+ sxp (~> 1.3)
68
70
  unicode-types (~> 1.8)
69
71
  edtf (3.1.1)
70
72
  activesupport (>= 3.0, < 8.0)
@@ -76,9 +78,6 @@ GEM
76
78
  ffi (>= 1.0.0)
77
79
  rake
78
80
  gender_detector (2.0.0)
79
- haml (5.2.2)
80
- temple (>= 0.8.0)
81
- tilt
82
81
  hana (1.3.7)
83
82
  hashdiff (1.0.1)
84
83
  htmlentities (4.3.4)
@@ -95,16 +94,16 @@ GEM
95
94
  iniparser (1.0.1)
96
95
  json (2.6.3)
97
96
  json-canonicalization (0.3.2)
98
- json-ld (3.2.5)
97
+ json-ld (3.3.0)
99
98
  htmlentities (~> 4.3)
100
99
  json-canonicalization (~> 0.3, >= 0.3.2)
101
100
  link_header (~> 0.0, >= 0.0.8)
102
101
  multi_json (~> 1.15)
103
102
  rack (>= 2.2, < 4)
104
- rdf (~> 3.2, >= 3.2.10)
105
- json-ld-preloaded (3.2.2)
106
- json-ld (~> 3.2)
107
- rdf (~> 3.2)
103
+ rdf (~> 3.3)
104
+ json-ld-preloaded (3.3.0)
105
+ json-ld (~> 3.3)
106
+ rdf (~> 3.3)
108
107
  json_schemer (1.0.3)
109
108
  hana (~> 1.3)
110
109
  regexp_parser (~> 2.0)
@@ -124,13 +123,13 @@ GEM
124
123
  crass (~> 1.0.2)
125
124
  nokogiri (>= 1.12.0)
126
125
  matrix (0.4.2)
127
- minitest (5.18.1)
126
+ minitest (5.20.0)
128
127
  multi_json (1.15.0)
129
128
  namae (1.1.1)
130
- nokogiri (1.15.3-arm64-darwin)
129
+ nokogiri (1.15.4-arm64-darwin)
131
130
  racc (~> 1.4)
132
- oj (3.15.0)
133
- optimist (3.0.1)
131
+ oj (3.16.1)
132
+ optimist (3.1.0)
134
133
  parallel (1.23.0)
135
134
  parser (3.2.2.3)
136
135
  ast (~> 2.4.1)
@@ -148,33 +147,22 @@ GEM
148
147
  rack (>= 1.3)
149
148
  rainbow (3.1.1)
150
149
  rake (13.0.6)
151
- rdf (3.2.11)
150
+ rdf (3.3.0)
151
+ bcp47_spec (~> 0.2)
152
152
  link_header (~> 0.0, >= 0.0.8)
153
- rdf-aggregate-repo (3.2.1)
154
- rdf (~> 3.2)
155
- rdf-rdfa (3.2.2)
156
- haml (>= 5.2, < 7)
157
- htmlentities (~> 4.3)
158
- rdf (~> 3.2)
159
- rdf-aggregate-repo (~> 3.2)
160
- rdf-vocab (~> 3.2)
161
- rdf-xsd (~> 3.2)
162
- rdf-rdfxml (3.2.1)
163
- haml (~> 5.2)
153
+ rdf-rdfxml (3.3.0)
154
+ builder (~> 3.2, >= 3.2.4)
164
155
  htmlentities (~> 4.3)
165
- rdf (~> 3.2)
166
- rdf-rdfa (~> 3.2)
167
- rdf-xsd (~> 3.2)
168
- rdf-turtle (3.2.1)
169
- ebnf (~> 2.3)
170
- rdf (~> 3.2)
171
- rdf-vocab (3.2.6)
172
- rdf (~> 3.2, >= 3.2.4)
173
- rdf-xsd (3.2.1)
174
- rdf (~> 3.2)
156
+ rdf (~> 3.3)
157
+ rdf-xsd (~> 3.3)
158
+ rdf-turtle (3.3.0)
159
+ ebnf (~> 2.4)
160
+ rdf (~> 3.3)
161
+ rdf-xsd (3.3.0)
162
+ rdf (~> 3.3)
175
163
  rexml (~> 3.2)
176
164
  regexp_parser (2.8.1)
177
- rexml (3.2.5)
165
+ rexml (3.2.6)
178
166
  rspec (3.12.0)
179
167
  rspec-core (~> 3.12.0)
180
168
  rspec-expectations (~> 3.12.0)
@@ -184,14 +172,15 @@ GEM
184
172
  rspec-expectations (3.12.3)
185
173
  diff-lcs (>= 1.2.0, < 2.0)
186
174
  rspec-support (~> 3.12.0)
187
- rspec-mocks (3.12.5)
175
+ rspec-mocks (3.12.6)
188
176
  diff-lcs (>= 1.2.0, < 2.0)
189
177
  rspec-support (~> 3.12.0)
190
178
  rspec-support (3.12.1)
191
179
  rspec-xsd (0.1.0)
192
180
  nokogiri (~> 1.6)
193
181
  rspec (~> 3)
194
- rubocop (1.54.1)
182
+ rubocop (1.56.2)
183
+ base64 (~> 0.1.1)
195
184
  json (~> 2.3)
196
185
  language_server-protocol (>= 3.17.0)
197
186
  parallel (~> 1.10)
@@ -199,7 +188,7 @@ GEM
199
188
  rainbow (>= 2.2.2, < 4.0)
200
189
  regexp_parser (>= 1.8, < 3.0)
201
190
  rexml (>= 3.2.5, < 4.0)
202
- rubocop-ast (>= 1.28.0, < 2.0)
191
+ rubocop-ast (>= 1.28.1, < 2.0)
203
192
  ruby-progressbar (~> 1.7)
204
193
  unicode-display_width (>= 2.4.0, < 3.0)
205
194
  rubocop-ast (1.29.0)
@@ -208,12 +197,12 @@ GEM
208
197
  rubocop (~> 1.41)
209
198
  rubocop-factory_bot (2.23.1)
210
199
  rubocop (~> 1.33)
211
- rubocop-performance (1.18.0)
200
+ rubocop-performance (1.19.0)
212
201
  rubocop (>= 1.7.0, < 2.0)
213
202
  rubocop-ast (>= 0.4.0)
214
203
  rubocop-rake (0.6.0)
215
204
  rubocop (~> 1.0)
216
- rubocop-rspec (2.22.0)
205
+ rubocop-rspec (2.23.2)
217
206
  rubocop (~> 1.33)
218
207
  rubocop-capybara (~> 2.17)
219
208
  rubocop-factory_bot (~> 2.22)
@@ -228,17 +217,15 @@ GEM
228
217
  simplecov_json_formatter (0.1.4)
229
218
  simpleidn (0.2.1)
230
219
  unf (~> 0.1.4)
231
- sxp (1.2.4)
220
+ sxp (1.3.0)
232
221
  matrix (~> 0.4)
233
- rdf (~> 3.2)
234
- temple (0.10.2)
222
+ rdf (~> 3.3)
235
223
  textutils (1.4.0)
236
224
  activesupport
237
225
  logutils (>= 0.6.1)
238
226
  props (>= 1.1.2)
239
227
  rubyzip (>= 1.0.0)
240
228
  thor (1.2.2)
241
- tilt (2.2.0)
242
229
  tzinfo (2.0.6)
243
230
  concurrent-ruby (~> 1.0)
244
231
  unf (0.1.4)
@@ -248,7 +235,7 @@ GEM
248
235
  unicode-types (1.8.0)
249
236
  uuidtools (2.2.0)
250
237
  vcr (6.2.0)
251
- webmock (3.18.1)
238
+ webmock (3.19.1)
252
239
  addressable (>= 2.8.0)
253
240
  crack (>= 0.3.2)
254
241
  hashdiff (>= 0.4.0, < 2.0.0)
data/bin/commonmeta CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require File.expand_path("../../lib/commonmeta", __FILE__)
4
4
 
5
- if (ARGV & %w(--version -v help --help encode decode encode_id decode_id encode_by_blog encode_by_id json_feed_not_indexed json_feed_unregistered json_feed_by_blog update_ghost_post)).empty?
5
+ if (ARGV & %w(--version -v help --help encode decode encode_id decode_id encode_by_blog encode_by_id json_feed_not_indexed json_feed_unregistered json_feed_by_blog update_ghost_post generate_ghost_api_token)).empty?
6
6
  Commonmeta::CLI.start(ARGV.dup.unshift("convert"))
7
7
  else
8
8
  Commonmeta::CLI.start
@@ -121,6 +121,13 @@ module Commonmeta
121
121
  puts update_ghost_post_via_api(id)
122
122
  end
123
123
 
124
+ desc "", "generate_ghost_api_token"
125
+
126
+ def generate_ghost_api_token
127
+ # generate short lived jwt for ghost admin api
128
+ puts generate_ghost_token
129
+ end
130
+
124
131
  default_task :convert
125
132
  end
126
133
  end
@@ -63,6 +63,7 @@ module Commonmeta
63
63
  insert_crossref_issn(xml)
64
64
  insert_item_number(xml)
65
65
  insert_crossref_access_indicators(xml)
66
+ insert_crossref_relations(xml)
66
67
  insert_doi_data(xml)
67
68
  insert_citation_list(xml)
68
69
  end
@@ -81,6 +82,7 @@ module Commonmeta
81
82
  insert_item_number(xml)
82
83
  insert_crossref_abstract(xml)
83
84
  insert_crossref_access_indicators(xml)
85
+ insert_crossref_relations(xml)
84
86
  insert_doi_data(xml)
85
87
  insert_citation_list(xml)
86
88
  end
@@ -197,6 +199,24 @@ module Commonmeta
197
199
  end
198
200
  end
199
201
 
202
+ def insert_crossref_relations(xml)
203
+ return xml if related_identifiers.blank?
204
+
205
+ xml.program("xmlns" => "http://www.crossref.org/relations.xsd",
206
+ "name" => "relations") do
207
+ related_identifiers.each do |related_identifier|
208
+ identifier_type = validate_doi(related_identifier["id"]) ? "doi" : "url"
209
+ id = identifier_type == "doi" ? doi_from_url(related_identifier["id"]) : related_identifier["id"]
210
+ attributes = {
211
+ "relation_type" => related_identifier["type"].camelize(:lower),
212
+ "identifier_type" => identifier_type,
213
+ }.compact
214
+
215
+ xml.intra_work_relation(id, attributes)
216
+ end
217
+ end
218
+ end
219
+
200
220
  # def insert_dates(xml)
201
221
  # return xml unless Array.wrap(dates).present?
202
222
 
@@ -57,11 +57,12 @@ module Commonmeta
57
57
  language = meta.fetch("language", nil) || meta.dig("blog", "language")
58
58
  state = id.present? || read_options.present? ? "findable" : "not_found"
59
59
  subjects = Array.wrap(meta.dig("blog", "category")).reduce([]) do |sum, subject|
60
- sum += name_to_fos(subject)
60
+ sum += name_to_fos(subject.underscore.humanize)
61
61
 
62
62
  sum
63
63
  end
64
64
  references = get_references(meta)
65
+ related_identifiers = get_related_identifiers(meta)
65
66
  alternate_identifiers = [{ "alternateIdentifier" => meta["id"], "alternateIdentifierType" => "UUID" }]
66
67
 
67
68
  { "id" => id,
@@ -77,6 +78,7 @@ module Commonmeta
77
78
  "license" => license,
78
79
  "subjects" => subjects.presence,
79
80
  "references" => references.presence,
81
+ "related_identifiers" => related_identifiers.presence,
80
82
  "alternate_identifiers" => alternate_identifiers,
81
83
  "state" => state }.compact.merge(read_options)
82
84
  end
@@ -103,6 +105,22 @@ module Commonmeta
103
105
  end
104
106
  end
105
107
 
108
+ def get_related_identifiers(meta)
109
+ # check that relationships resolve
110
+ Array.wrap(meta["relationships"]).reduce([]) do |sum, relationship|
111
+ begin
112
+ if [200, 301, 302].include? HTTP.head(relationship["url"]).status
113
+ sum << { "id" => relationship["url"], "type" => relationship["type"] }
114
+ end
115
+ rescue => error
116
+ # puts "Error: #{error.message}"
117
+ # puts "Error: #{reference}"
118
+ end
119
+
120
+ sum
121
+ end
122
+ end
123
+
106
124
  def get_json_feed_unregistered
107
125
  # get JSON Feed items not registered as DOIs
108
126
 
@@ -5,7 +5,7 @@ require "pathname"
5
5
 
6
6
  module Commonmeta
7
7
  module SchemaUtils
8
- COMMONMETA = File.read(File.expand_path("../../resources/commonmeta_v0.9.2.json",
8
+ COMMONMETA = File.read(File.expand_path("../../resources/commonmeta_v0.9.3.json",
9
9
  __dir__))
10
10
 
11
11
  def json_schema_errors
@@ -1096,14 +1096,14 @@ module Commonmeta
1096
1096
 
1097
1097
  # parsing of unix timestamps such as 1427846400
1098
1098
  def get_datetime_from_unix_timestamp(unix_timestamp)
1099
- strip_milliseconds(DateTime.strptime(unix_timestamp.to_s, '%s').iso8601)
1099
+ strip_milliseconds(DateTime.strptime(unix_timestamp.to_s, "%s").iso8601)
1100
1100
  rescue StandardError
1101
1101
  nil
1102
1102
  end
1103
1103
 
1104
1104
  # parsing of unix timestamps such as 1427846400
1105
1105
  def get_date_from_unix_timestamp(unix_timestamp)
1106
- DateTime.strptime(unix_timestamp.to_s, '%s').strftime('%Y-%m-%d')
1106
+ DateTime.strptime(unix_timestamp.to_s, "%s").strftime("%Y-%m-%d")
1107
1107
  rescue StandardError
1108
1108
  nil
1109
1109
  end
@@ -1467,9 +1467,11 @@ module Commonmeta
1467
1467
  "https://rogue-scholar.org/api/posts/#{id}"
1468
1468
  end
1469
1469
 
1470
- def generate_ghost_token(admin_api_key)
1470
+ def generate_ghost_token(admin_api_key = ENV["API_KEY"])
1471
1471
  # from https://ghost.org/docs/admin-api/
1472
1472
 
1473
+ return nil unless admin_api_key.present?
1474
+
1473
1475
  # Split the key into ID and SECRET
1474
1476
  id, secret = admin_api_key.split(":")
1475
1477
 
@@ -1522,7 +1524,7 @@ module Commonmeta
1522
1524
 
1523
1525
  # update post canonical_url with new doi
1524
1526
  ghost_url = "#{api_url}/ghost/api/admin/posts/#{ghost_id}/"
1525
- response = HTTP.auth("Ghost #{ghost_jwt}").headers('Content-Type' => "application/json", 'Accept-Version' => 'v5').put(ghost_url, :json => { 'posts' => [{ 'canonical_url' => doi, 'updated_at' => updated_at }] })
1527
+ response = HTTP.auth("Ghost #{ghost_jwt}").headers("Content-Type" => "application/json", "Accept-Version" => "v5").put(ghost_url, :json => { "posts" => [{ "canonical_url" => doi, "updated_at" => updated_at }] })
1526
1528
  "#{response.status} DOI #{doi} added to post #{ghost_id}"
1527
1529
  end
1528
1530
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Commonmeta
4
- VERSION = '3.3.17'
4
+ VERSION = '3.4.0'
5
5
  end
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "https://commonmeta.org/commonmeta_v0.9.2.json",
4
- "title": "Commonmeta v0.9.2",
3
+ "$id": "https://commonmeta.org/commonmeta_v0.9.3.json",
4
+ "title": "Commonmeta v0.9.3",
5
5
  "description": "JSON representation of the Commonmeta schema.",
6
6
  "additionalProperties": false,
7
7
  "definitions": {
@@ -288,6 +288,36 @@
288
288
  },
289
289
  "uniqueItems": true
290
290
  },
291
+ "related_identifiers": {
292
+ "description": "Other resolvable persistent unique IDs related to the resource.",
293
+ "type": "array",
294
+ "items": {
295
+ "type": "object",
296
+ "properties": {
297
+ "id": {
298
+ "type": "string"
299
+ },
300
+ "type": {
301
+ "type": "string",
302
+ "enum": [
303
+ "IsIdenticalTo",
304
+ "IsNewVersionOf",
305
+ "IsPreviousVersionOf",
306
+ "IsPartOf",
307
+ "HasPart",
308
+ "IsVariantFormOf",
309
+ "IsTranslationOf",
310
+ "IsVersionOf",
311
+ "IsReviewOf",
312
+ "IsPreprintOf",
313
+ "HasPreprint"
314
+ ]
315
+ }
316
+ },
317
+ "required": ["id", "type"]
318
+ },
319
+ "uniqueItems": true
320
+ },
291
321
  "funding_references": {
292
322
  "description": "The funding references for the resource.",
293
323
  "type": "array",
data/spec/cli_spec.rb CHANGED
@@ -371,7 +371,7 @@ describe Commonmeta::CLI do
371
371
  end
372
372
 
373
373
  it "json_feed_not_indexed" do
374
- expect { subject.json_feed_not_indexed }.to output(/b1038a3f-c5aa-4a68-97cb-5c68b27942f7/).to_stdout
374
+ expect { subject.json_feed_not_indexed }.to output(/r294649-6f79289-8cw1w/).to_stdout
375
375
  end
376
376
 
377
377
  it "json_feed_by_blog" do
@@ -23,13 +23,13 @@ http_interactions:
23
23
  Cache-Control:
24
24
  - public, max-age=0, must-revalidate
25
25
  Content-Length:
26
- - '2106'
26
+ - '8527'
27
27
  Content-Type:
28
28
  - application/json; charset=utf-8
29
29
  Date:
30
- - Mon, 10 Jul 2023 21:04:54 GMT
30
+ - Wed, 06 Sep 2023 14:27:24 GMT
31
31
  Etag:
32
- - '"13pz9o7pqcg1mi"'
32
+ - '"sk275cf3ap6kl"'
33
33
  Server:
34
34
  - Vercel
35
35
  Strict-Transport-Security:
@@ -39,7 +39,7 @@ http_interactions:
39
39
  X-Vercel-Cache:
40
40
  - MISS
41
41
  X-Vercel-Id:
42
- - fra1::iad1::jbp2f-1689023094094-f2a6094c04f1
42
+ - fra1::iad1::bsggp-1694010443675-85c6731865df
43
43
  Connection:
44
44
  - close
45
45
  body:
@@ -49,18 +49,84 @@ http_interactions:
49
49
  before sunset in Tucson. Live image below, showing the glorious Santa Catalina
50
50
  mountains (the snow on the upper reaches is more apparent earlier in the day)
51
51
  and my dinner preparations (shrimp and veggies on the grill).I''ve decided
52
- to start writing here at Quintessence of Dust, after another long hiatus.
53
- Here are some of my reasons.1. I like to write, and I have things to say,
54
- and I self-identify as an author. For eight years, I have co-organized and
55
- taught in...","published_at":1673233380,"updated_at":1680470227,"indexed_at":1689006804,"authors":[{"url":null,"name":"Stephen
56
- Matheson"}],"image":null,"tags":["Introduction"],"language":"en","reference":[],"blog_id":"5764g49","blog_name":"Quintessence
57
- of Dust","blog":{"id":"5764g49","title":"Quintessence of Dust","description":"<i>Quintessence
58
- of Dust</i> explores science, society, and human nature, focusing on genetics,
59
- development, evolution, neuroscience, systems biology, and topics related
60
- to scientific literacy. I occasionally discuss intelligent design, creationism,
61
- science denial, and other political/social influences on scientific literacy.
62
- Additional topics: philosophy, baseball, scientific culture, and Shakespeare.
63
- My main theme is <b><u>scientific explanation</u></b>.","language":"en","favicon":null,"feed_url":"http://sfmatheson.blogspot.com/feeds/posts/default","home_page_url":"http://sfmatheson.blogspot.com/","user_id":"8498eaf6-8c58-4b58-bc15-27eda292b1aa","created_at":"2023-05-31T14:21:27+00:00","indexed_at":"2023-04-18","feed_format":"application/atom+xml","license":"https://creativecommons.org/licenses/by/4.0/legalcode","generator":"Blogger
64
- 7.00","category":"Social Sciences","prefix":"10.59350","modified_at":"2023-07-05T03:41:45+00:00","version":"https://jsonfeed.org/version/1.1","backlog":true,"current_feed_url":null,"expired":null}}'
65
- recorded_at: Mon, 10 Jul 2023 21:04:54 GMT
52
+ to start writing here at <i>Quintessence of Dust</i>, after another long hiatus.","content_html":"It''s
53
+ early January 2023, a little before sunset in Tucson. Live image below, showing
54
+ the glorious Santa Catalina mountains (the snow on the upper reaches is more
55
+ apparent earlier in the day) and my dinner preparations (shrimp and veggies
56
+ on the grill).<div><a href=\"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghgBx9BU21qMDFnLxgHmnsl6TQVfb3QCwOXrC1zcXq7WH9gN8E0TcH3pTslRBG6O8mb5gcuF9JVtDlJ2je6dFcfyzKE4OD38-ftr66nBxddo892_NkyuevrrX65ndSbwmXMaLh3F5yiqU1QIj8JtA8FLkKOcHOEVwVafz0rzh7PejbFzp3XT25nQxc/s4032/Jan%207.jpg\"><img
57
+ height=\"320\" src=\"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghgBx9BU21qMDFnLxgHmnsl6TQVfb3QCwOXrC1zcXq7WH9gN8E0TcH3pTslRBG6O8mb5gcuF9JVtDlJ2je6dFcfyzKE4OD38-ftr66nBxddo892_NkyuevrrX65ndSbwmXMaLh3F5yiqU1QIj8JtA8FLkKOcHOEVwVafz0rzh7PejbFzp3XT25nQxc/s320/Jan%207.jpg\"
58
+ width=\"240\" /></a></div><br /><div><div>I''ve decided to start writing here
59
+ at <i>Quintessence of Dust</i>, after another long hiatus. Here are some of
60
+ my reasons.</div><div><br /></div><div>1. I like to write, and I have things
61
+ to say, and I self-identify as an author. For eight years, I have co-organized
62
+ and taught in the <a href=\"https://meetings.cshl.edu/courses.aspx?course=C-WRITE&amp;year=23\"
63
+ target=\"_blank\">Scientific Writing Retreat at Cold Spring Harbor Laboratory</a>.
64
+ I''m a writer and I need to write, if only for myself.</div><div><br /></div><div>2.
65
+ I have an idea for a book, along with some introductory work (but no sample
66
+ chapters yet) and writing here will help me develop those thoughts. The idea
67
+ is over twelve years old and has never faded away, which I take to mean that
68
+ I need to get it out of my system somehow.</div><div><br /></div><div>3. I
69
+ have other ideas kicking around in my head and most of them are worth writing
70
+ about. I have one new intellectual passion that is totally worth writing about:
71
+ <a href=\"https://skyislandalliance.org/the-sky-islands/\" target=\"_blank\">the
72
+ Sky Islands</a> that nearly surround us here in Tucson.</div><div><br /></div><div>4.
73
+ I have an exciting new job with great new people at <a href=\"https://plos.org/\"
74
+ target=\"_blank\">an organization</a> that''s all in for <a href=\"https://plos.org/open-science/\"
75
+ target=\"_blank\">open science</a>. I recently turned over the tens digit
76
+ on my age-o-meter. My kids will very soon be all out of college. (One is about
77
+ to start a postdoc!) All of this led, predictably, to a spasm of reflection
78
+ on projects and vision. One clear result is that I''m feeling more inspired.<span><a
79
+ name=\"more\"></a></span></div><div><br /></div><div>5. The demise of Twitter
80
+ has led to a lot of <a href=\"https://www.theatlantic.com/technology/archive/2022/11/twitter-facebook-social-media-decline/672074/\"
81
+ target=\"_blank\">useful commentary</a> about the nature of social media.
82
+ I left Facebook two years ago and all but left Twitter two months ago. I''m
83
+ on a <a href=\"https://fediscience.org/explore\" target=\"_blank\">good server
84
+ at Mastodon</a> and I like it; maybe microblogging there can satisfy my desire
85
+ for conversation and connection. But <a href=\"https://www.theverge.com/23513418/bring-back-personal-blogging\"
86
+ target=\"_blank\">this recent piece</a> at <i>The Verge</i> by <a href=\"https://moniquejudge.com/\"
87
+ target=\"_blank\">Monique Judge</a> convinced me that blogging could (again)
88
+ have a place in the future.</div><div><br /><div>Here''s her summary, emphasis
89
+ mine:</div><div><blockquote>At the end of the day, we don’t know what is going
90
+ to happen next with Twitter or any of these platforms. We don’t know what
91
+ changes <a href=\"https://www.techtarget.com/whatis/definition/Web-30\" target=\"_blank\">Web
92
+ 3.0</a> is going to bring to the internet. We do know that <b>we will all
93
+ still be here, wanting to share our thoughts, talk about anything and everything,
94
+ and commune with our people</b>. Personal blogging is the simplest and fastest
95
+ way to do all of that. </blockquote></div><div>That''s what I want! A place
96
+ to write, and (if I''m lucky) a place to discuss and \"commune\" with people.
97
+ That used to happen a lot at <i>Quintessence of Dust</i>.<span></span></div></div></div><div><br
98
+ /></div><div>Okay, but why here? This blog is over 15 years old and was started
99
+ when I was a Christian believer. <a href=\"https://sfmatheson.blogspot.com/2007/08/kicking-off-my-blog.html\"
100
+ target=\"_blank\">Its founding themes</a> were anchored in a desire to help
101
+ Christians understand and enjoy biology, to help them shake free of misinformation
102
+ and dishonesty. It has twice languished through long hiatuses and was <a href=\"https://sfmatheson.blogspot.com/p/about.html\"
103
+ target=\"_blank\">remodeled</a> back in 2017 a few years after I deconverted.
104
+ Maybe it''s time to start anew? I think not, for many of those same reasons:
105
+ I''m still a biologist who loves science, still worried about misinformation,
106
+ and still rooted in the power of scientific explanation. I''m still a bardolator
107
+ and a Red Sox fan. <a href=\"https://sfmatheson.blogspot.com/p/about.html\">I''m
108
+ still me</a>, and <i>Quintessence of Dust</i> is still my blog. The new <a
109
+ href=\"https://sfmatheson.blogspot.com/p/about.html\" target=\"_blank\">About
110
+ page</a> is slightly remodeled from 2017, and hints at the next post, which
111
+ will outline some new goals and ongoing projects.</div><div><br /></div><div>A
112
+ final note on inspiration, from Imani Perry, writing in her newsletter (<a
113
+ href=\"https://newsletters.theatlantic.com/unsettled-territory/\" target=\"_blank\">Unsettled
114
+ Territory</a>) at <i>The Atlantic</i>. The piece is \"<a href=\"https://newsletters.theatlantic.com/unsettled-territory/63af3facace609003751bacc/becoming-writer-habit-journalism/\"
115
+ target=\"_blank\">Writing is a Democratic Art</a>.\" It''s for subscribers
116
+ only but here is her challenge:</div><div><blockquote>Thinking and writing
117
+ at a faster pace stretched me and gave me greater confidence. Sometimes I
118
+ changed my mind about what I’d written a day later. But that was okay; a newsletter
119
+ is a moment in time. Writing it each week gave me a lovely rhythm in what
120
+ has otherwise been a difficult and disorienting season in history. Feeling
121
+ stuck can get you stuck. But writing can, and should, inspire deeds.</blockquote></div>","published_at":1673233380,"updated_at":1680470227,"indexed_at":1689006804,"authors":[{"url":null,"name":"Stephen
122
+ Matheson"}],"image":"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghgBx9BU21qMDFnLxgHmnsl6TQVfb3QCwOXrC1zcXq7WH9gN8E0TcH3pTslRBG6O8mb5gcuF9JVtDlJ2je6dFcfyzKE4OD38-ftr66nBxddo892_NkyuevrrX65ndSbwmXMaLh3F5yiqU1QIj8JtA8FLkKOcHOEVwVafz0rzh7PejbFzp3XT25nQxc/s320/Jan%207.jpg","tags":["Introduction"],"language":"en","reference":[],"relationships":[],"blog_id":"5764g49","blog_name":"Quintessence
123
+ of Dust","blog_slug":"sfmatheson","blog":{"id":"5764g49","title":"Quintessence
124
+ of Dust","description":"<i>Quintessence of Dust</i> explores science, society,
125
+ and human nature, focusing on genetics, development, evolution, neuroscience,
126
+ systems biology, and topics related to scientific literacy. I occasionally
127
+ discuss intelligent design, creationism, science denial, and other political/social
128
+ influences on scientific literacy. Additional topics: philosophy, baseball,
129
+ scientific culture, and Shakespeare. My main theme is <b><u>scientific explanation</u></b>.","language":"en","favicon":null,"feed_url":"http://sfmatheson.blogspot.com/feeds/posts/default","home_page_url":"http://sfmatheson.blogspot.com","user_id":"656f9875-3304-4056-935b-b29429e14222","created_at":"2023-04-18","feed_format":"application/atom+xml","license":"https://creativecommons.org/licenses/by/4.0/legalcode","generator":"Blogger
130
+ 7.00","category":"socialSciences","prefix":"10.59350","modified_at":"2023-08-17T05:24:17+00:00","version":"https://jsonfeed.org/version/1.1","current_feed_url":null,"status":"active","issn":null,"backlog":0,"authors":null,"plan":"Team","slug":"sfmatheson","use_mastodon":false}}'
131
+ recorded_at: Wed, 06 Sep 2023 14:27:24 GMT
66
132
  recorded_with: VCR 6.2.0